aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-05-21 19:30:55 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-05-21 19:30:55 +0200
commitfff7c41f6208c8572f34af2f0ad7160c2d9cb9c5 (patch)
treef3b7af54ba237e3f178b8997644fd6c306b563d7
parentd8bd0e26174f31b25d92189d640fce6f58e92ace (diff)
POTD skeleton #70.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--src/jail.c8
-rw-r--r--src/pseccomp.c3
-rw-r--r--src/utils.c101
-rw-r--r--src/utils.h4
4 files changed, 115 insertions, 1 deletions
diff --git a/src/jail.c b/src/jail.c
index d0da50b..564e611 100644
--- a/src/jail.c
+++ b/src/jail.c
@@ -168,6 +168,10 @@ static int jail_mainloop(event_ctx **ev_ctx, const jail_ctx *ctx[], size_t siz)
set_procname("[potd] jail");
assert( set_child_sighandler() == 0 );
+ D2("%s", "Setup cgroups");
+ if (cgroups_set())
+ FATAL("%s", "Setup cgroups");
+
rc = event_loop(*ev_ctx, jail_accept_client, &ev_jail);
event_free(ev_ctx);
@@ -259,6 +263,10 @@ static int jail_childfn(prisoner_process *ctx)
if (clearenv())
FATAL("Clearing ENV for pid %d", self_pid);
+ D2("Activating cgroups for pid %d", self_pid);
+ if (cgroups_activate())
+ FATAL("Activating cgroups for pid %d", self_pid);
+
caps_drop_dac_override(0);
//caps_drop_all();
diff --git a/src/pseccomp.c b/src/pseccomp.c
index 97504d2..c794fdb 100644
--- a/src/pseccomp.c
+++ b/src/pseccomp.c
@@ -36,7 +36,8 @@ static const int default_allowed_syscalls[] = {
SCMP_SYS(getpgrp), SCMP_SYS(setpgid), SCMP_SYS(getpid), SCMP_SYS(kill),
SCMP_SYS(unshare), SCMP_SYS(chroot), SCMP_SYS(chdir), SCMP_SYS(mount),
SCMP_SYS(umount2),
- SCMP_SYS(mknod), SCMP_SYS(mkdir), SCMP_SYS(statfs), SCMP_SYS(ioctl),
+ SCMP_SYS(mknod), SCMP_SYS(mkdir), SCMP_SYS(rmdir),
+ SCMP_SYS(statfs), SCMP_SYS(ioctl),
SCMP_SYS(chown), SCMP_SYS(chmod), SCMP_SYS(setsid), SCMP_SYS(dup2),
SCMP_SYS(sethostname), SCMP_SYS(uname), SCMP_SYS(arch_prctl)
};
diff --git a/src/utils.c b/src/utils.c
index 34982d1..9fd1a24 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -24,9 +24,14 @@
char *arg0 = NULL;
static int null_fd = -1;
+static const char cgmem[] = "/sys/fs/cgroup/memory/potd";
+static const char cgcpu[] = "/sys/fs/cgroup/cpu/potd";
+static const char cgpid[] = "/sys/fs/cgroup/pids/potd";
static void sighandler_child(int signo);
static void sighandler_master(int signo);
+static int cgroups_write_file(const char *cdir, const char *csub,
+ const char *value, size_t siz);
static inline void bin2hex_char(unsigned char c, char hexc[5]);
@@ -427,6 +432,102 @@ int create_device_files(const char *mount_path)
return s;
}
+static int cgroups_write_file(const char *cdir, const char *csub,
+ const char *value, size_t siz)
+{
+ int fd, s = 0;
+ char buf[BUFSIZ] = {0};
+
+ assert(cdir && csub && value);
+
+ D2("Write '%s' to '%s/%s'", value, cdir, csub);
+ if (snprintf(buf, sizeof buf, "%s/%s", cdir, csub) > 0) {
+ if ((fd = open(buf, O_WRONLY)) < 0 ||
+ write(fd, value, siz) <= 0)
+ {
+ E_STRERR("Write '%s' to '%s/%s'",
+ value, cdir, csub);
+ s = 1;
+ }
+ close(fd);
+ }
+
+ return s;
+}
+
+int cgroups_set(void)
+{
+ int s = 0;
+ const char maxmem[] = "memory.limit_in_bytes";
+ const char maxmem_soft[] = "memory.soft_limit_in_bytes";
+ const char kmem[] = "memory.kmem.limit_in_bytes";
+ const char kmem_tcp[] = "memory.kmem.tcp.limit_in_bytes";
+ const char maxmem_limit[] = "8388608"; /* 8*1024*1024 = 8MB */
+ const char maxmem_soft_limit[] = "7340032"; /* 7*1024*1024 = 8MB */
+ const char cpu_shares[] = "cpu.shares";
+ const char cpu_shares_limit[] = "32";
+ const char cfs_period[] = "cpu.cfs_period_us";
+ const char cfs_period_limit[] = "50000";
+ const char cfs_quota[] = "cpu.cfs_quota_us";
+ const char cfs_quota_limit[] = "10000";
+ const char pid_max[] = "pids.max";
+ const char pid_max_limit[] = "5";
+
+ if (remove(cgmem) && errno != ENOENT)
+ return 1;
+ s |= mkdir(cgmem,
+ S_IRUSR|S_IWUSR|S_IXUSR | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
+ if (remove(cgcpu) && errno != ENOENT)
+ return 1;
+ s |= mkdir(cgcpu,
+ S_IRUSR|S_IWUSR|S_IXUSR | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
+ if (remove(cgpid) && errno != ENOENT)
+ return 1;
+ s |= mkdir(cgpid,
+ S_IRUSR|S_IWUSR|S_IXUSR | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH);
+
+ s |= cgroups_write_file(cgmem, maxmem, maxmem_limit, sizeof maxmem_limit);
+ s |= cgroups_write_file(cgmem, maxmem_soft, maxmem_soft_limit,
+ sizeof maxmem_limit);
+ s |= cgroups_write_file(cgmem, kmem_tcp, maxmem_limit, sizeof maxmem_limit);
+ s |= cgroups_write_file(cgmem, kmem, maxmem_limit, sizeof maxmem_limit);
+ s |= cgroups_write_file(cgcpu, cpu_shares, cpu_shares_limit,
+ sizeof cpu_shares_limit);
+ s |= cgroups_write_file(cgcpu, cfs_period, cfs_period_limit,
+ sizeof cfs_period_limit);
+ s |= cgroups_write_file(cgcpu, cfs_quota, cfs_quota_limit,
+ sizeof cfs_quota_limit);
+ s |= cgroups_write_file(cgpid, pid_max, pid_max_limit,
+ sizeof pid_max_limit);
+
+ return s;
+}
+
+int cgroups_activate(void)
+{
+ pid_t p = getpid();
+ int s;
+ char buf[32] = {0};
+ const char tasks[] = "tasks";
+
+ s = snprintf(buf, sizeof buf, "%d", p);
+ if (s <= 0)
+ return 1;
+ s = cgroups_write_file(cgmem, tasks, buf, s);
+
+ s = snprintf(buf, sizeof buf, "%d", p);
+ if (s <= 0)
+ return 1;
+ s = cgroups_write_file(cgcpu, tasks, buf, s);
+
+ s = snprintf(buf, sizeof buf, "%d", p);
+ if (s <= 0)
+ return 1;
+ s = cgroups_write_file(cgpid, tasks, buf, s);
+
+ return s;
+}
+
#if 0
int update_guid_map(pid_t pid, unsigned int map[3], int update_uidmap)
{
diff --git a/src/utils.h b/src/utils.h
index 83a7418..c46f9e5 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -49,6 +49,10 @@ int create_device_file_checked(const char *mount_path, const char *device_file,
int create_device_files(const char *mount_path);
+int cgroups_set(void);
+
+int cgroups_activate(void);
+
#if 0
int update_guid_map(pid_t pid, unsigned int uid_map[3], int update_uidmap);