aboutsummaryrefslogtreecommitdiff
path: root/libminijail.c
diff options
context:
space:
mode:
Diffstat (limited to 'libminijail.c')
-rw-r--r--libminijail.c47
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);