From 892499a01797263b0a3d6787d6a4be14f549de44 Mon Sep 17 00:00:00 2001 From: "Franklin \"Snaipe\" Mathieu" Date: Thu, 14 Nov 2024 18:37:29 +0100 Subject: [PATCH] cgroup: use proc fd when reading details about current process for explicitness --- cgroup.c | 21 +++++++++++++++++---- cgroup.h | 2 +- cgroup_native.c | 4 ++-- cgroup_systemd.c | 2 +- enter.c | 18 +++++++++++++++++- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/cgroup.c b/cgroup.c index 1ee22db..72a03ab 100644 --- a/cgroup.c +++ b/cgroup.c @@ -80,11 +80,24 @@ bool cgroup_current_path(char *path) return cgroup_drivers[cgroup_detected_driver]->current_path(path); } -bool cgroup_read_current(char *path) +bool cgroup_read_current(int procfd, char *path) { - FILE *selfcgroupfd = fopen("/proc/self/cgroup", "r"); - if (selfcgroupfd == NULL) { - err(1, "unable to derive current cgroup hierarchy from /proc/self/cgroup"); + FILE *selfcgroupfd; + if (procfd == -1) { + selfcgroupfd = fopen("/proc/self/cgroup", "r"); + if (!selfcgroupfd) { + err(1, "unable to derive current cgroup hierarchy from /proc/self/cgroup"); + } + } else { + int fd = openat(procfd, "cgroup", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + err(1, "unable to derive current cgroup hierarchy from /proc/self/cgroup"); + } + + selfcgroupfd = fdopen(fd, "r"); + if (!selfcgroupfd) { + err(1, "fdopen /proc/self/cgroup"); + } } const char *selfcgroup = NULL; diff --git a/cgroup.h b/cgroup.h index f5cf171..0e32cda 100644 --- a/cgroup.h +++ b/cgroup.h @@ -18,7 +18,7 @@ enum cgroup_driver { int cgroup_driver_init(enum cgroup_driver driver, bool fatal); bool cgroup_current_path(char *path); int cgroup_join(const char *parent, const char *name); -bool cgroup_read_current(char *path); +bool cgroup_read_current(int procfd, char *path); void cgroup_enable_controllers(int cgroupfd); void cgroup_start_cleaner(int parentfd, const char *name); diff --git a/cgroup_native.c b/cgroup_native.c index 4722357..0c4338b 100644 --- a/cgroup_native.c +++ b/cgroup_native.c @@ -12,7 +12,7 @@ static int cgroup_native_driver_init(bool fatal) { /* The native driver can only work with cgroup v2. Perform some sanity checks to verify this. */ - if (!cgroup_read_current(NULL)) { + if (!cgroup_read_current(-1, NULL)) { return -1; } @@ -35,7 +35,7 @@ static int cgroup_native_driver_init(bool fatal) static bool cgroup_native_current_path(char *path) { - return cgroup_read_current(path); + return cgroup_read_current(-1, path); } static int cgroup_native_join_cgroup(const char *parent, const char *name) diff --git a/cgroup_systemd.c b/cgroup_systemd.c index 6446c06..c4776e2 100644 --- a/cgroup_systemd.c +++ b/cgroup_systemd.c @@ -308,7 +308,7 @@ static int cgroup_systemd_join_cgroup(const char *parent, const char *name) } char selfcgroup[PATH_MAX]; - if (!cgroup_read_current(selfcgroup)) { + if (!cgroup_read_current(-1, selfcgroup)) { errx(1, "could not determine current cgroup; are you using cgroups v2?"); } int cgroupfd = open(selfcgroup, O_RDONLY | O_DIRECTORY, 0); diff --git a/enter.c b/enter.c index 2c8357e..c0ce055 100644 --- a/enter.c +++ b/enter.c @@ -131,6 +131,16 @@ static int cmp_epoll_handler(const void *a, const void *b) int enter(struct entry_settings *opts) { + int procfsfd = open("/proc", O_PATH | O_DIRECTORY | O_CLOEXEC); + if (procfsfd == -1) { + err(1, "open /proc"); + } + + int procfd = openat(procfsfd, "self", O_PATH | O_DIRECTORY | O_CLOEXEC); + if (procfd == -1) { + err(1, "open /proc/self"); + } + int timens_offsets = -1; if (opts->shares[NS_TIME] != SHARE_WITH_PARENT) { @@ -426,6 +436,12 @@ int enter(struct entry_settings *opts) } } + close(procfd); + procfd = openat(procfsfd, "self", O_PATH | O_DIRECTORY | O_CLOEXEC); + if (procfd == -1) { + err(1, "open /proc/self"); + } + close(liveness_fds[LIVENESS_KEEP]); /* err() and errx() cannot use exit(), since it's not fork-safe. */ @@ -451,7 +467,7 @@ int enter(struct entry_settings *opts) /* Read the current cgroup before ns_enter_postfork; this allows us to get the real path to the cgroup */ char cgroup_path[PATH_MAX]; - if (!cgroup_read_current(cgroup_path)) { + if (!cgroup_read_current(procfd, cgroup_path)) { cgroup_path[0] = '\0'; } ns_enter_postfork(namespaces, ns_len);