diff options
Diffstat (limited to 'libminijail.c')
-rw-r--r-- | libminijail.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/libminijail.c b/libminijail.c index 81cea4b..b119542 100644 --- a/libminijail.c +++ b/libminijail.c @@ -25,6 +25,7 @@ #include <sys/mount.h> #include <sys/param.h> #include <sys/prctl.h> +#include <sys/resource.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/user.h> @@ -74,9 +75,17 @@ #define MAX_CGROUPS 10 /* 10 different controllers supported by Linux. */ +#define MAX_RLIMITS 32 /* Currently there are 15 supported by Linux. */ + /* Keyctl commands. */ #define KEYCTL_JOIN_SESSION_KEYRING 1 +struct minijail_rlimit { + int type; + uint32_t cur; + uint32_t max; +}; + struct mountpoint { char *src; char *dest; @@ -155,6 +164,8 @@ struct minijail { size_t tmpfs_size; char *cgroups[MAX_CGROUPS]; size_t cgroup_count; + struct minijail_rlimit rlimits[MAX_RLIMITS]; + size_t rlimit_count; }; /* @@ -639,6 +650,26 @@ int API minijail_add_to_cgroup(struct minijail *j, const char *path) return 0; } +int API minijail_rlimit(struct minijail *j, int type, uint32_t cur, + uint32_t max) +{ + size_t i; + + if (j->rlimit_count >= MAX_RLIMITS) + return -ENOMEM; + /* It's an error if the caller sets the same rlimit multiple times. */ + for (i = 0; i < j->rlimit_count; i++) { + if (j->rlimits[i].type == type) + return -EEXIST; + } + + j->rlimits[j->rlimit_count].type = type; + j->rlimits[j->rlimit_count].cur = cur; + j->rlimits[j->rlimit_count].max = max; + j->rlimit_count++; + return 0; +} + int API minijail_forward_signals(struct minijail *j) { j->flags.forward_signals = 1; @@ -1307,6 +1338,19 @@ static void add_to_cgroups_or_die(const struct minijail *j) } } +static void set_rlimits_or_die(const struct minijail *j) +{ + size_t i; + + for (i = 0; i < j->rlimit_count; ++i) { + struct rlimit limit; + limit.rlim_cur = j->rlimits[i].cur; + limit.rlim_max = j->rlimits[i].max; + if (prlimit(j->initpid, j->rlimits[i].type, &limit, NULL)) + kill_child_and_die(j, "failed to set rlimit"); + } +} + static void write_ugid_maps_or_die(const struct minijail *j) { if (j->uidmap && write_proc_file(j->initpid, j->uidmap, "uid_map") != 0) @@ -2118,6 +2162,9 @@ int minijail_run_internal(struct minijail *j, const char *filename, if (j->flags.cgroups) add_to_cgroups_or_die(j); + if (j->rlimit_count) + set_rlimits_or_die(j); + if (j->flags.userns) write_ugid_maps_or_die(j); |