From: Mike Yuan Date: Fri, 28 Nov 2025 18:44:17 +0000 (+0100) Subject: core/exec-invoke: group setup_private_users*() together X-Git-Tag: v260-rc1~327^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ed05d641435b2490a59f09eb2e5fe2c1a66427d;p=thirdparty%2Fsystemd.git core/exec-invoke: group setup_private_users*() together --- diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index ebacec7fd9a..4f6ed63be67 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -2289,45 +2289,6 @@ static int build_pass_environment(const ExecContext *c, char ***ret) { return 0; } -static int setup_private_users_child(int unshare_ready_fd, const char *uid_map, const char *gid_map, bool allow_setgroups) { - int r; - - /* Child process, running in the original user namespace. Let's update the parent's UID/GID map from - * here, after the parent opened its own user namespace. */ - - pid_t ppid = getppid(); - - /* Wait until the parent unshared the user namespace */ - uint64_t c; - ssize_t n = read(unshare_ready_fd, &c, sizeof(c)); - if (n < 0) - return log_debug_errno(errno, "Failed to read from signaling eventfd: %m"); - if (n != sizeof(c)) - return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Short read from signaling eventfd."); - - /* Disable the setgroups() system call in the child user namespace, for good, unless PrivateUsers=full - * and using the system service manager. */ - const char *a = procfs_file_alloca(ppid, "setgroups"); - const char *setgroups = allow_setgroups ? "allow" : "deny"; - r = write_string_file(a, setgroups, WRITE_STRING_FILE_DISABLE_BUFFER); - if (r < 0) - return log_debug_errno(r, "Failed to write '%s' to %s: %m", setgroups, a); - - /* First write the GID map */ - a = procfs_file_alloca(ppid, "gid_map"); - r = write_string_file(a, gid_map, WRITE_STRING_FILE_DISABLE_BUFFER); - if (r < 0) - return log_debug_errno(r, "Failed to write GID map to %s: %m", a); - - /* Then write the UID map */ - a = procfs_file_alloca(ppid, "uid_map"); - r = write_string_file(a, uid_map, WRITE_STRING_FILE_DISABLE_BUFFER); - if (r < 0) - return log_debug_errno(r, "Failed to write UID map to %s: %m", a); - - return 0; -} - static int bpffs_helper(const ExecContext *c, int socket_fd) { assert(c); assert(socket_fd >= 0); @@ -2394,6 +2355,45 @@ static int bpffs_prepare( return 0; } +static int setup_private_users_child(int unshare_ready_fd, const char *uid_map, const char *gid_map, bool allow_setgroups) { + int r; + + /* Child process, running in the original user namespace. Let's update the parent's UID/GID map from + * here, after the parent opened its own user namespace. */ + + pid_t ppid = getppid(); + + /* Wait until the parent unshared the user namespace */ + uint64_t c; + ssize_t n = read(unshare_ready_fd, &c, sizeof(c)); + if (n < 0) + return log_debug_errno(errno, "Failed to read from signaling eventfd: %m"); + if (n != sizeof(c)) + return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Short read from signaling eventfd."); + + /* Disable the setgroups() system call in the child user namespace, for good, unless PrivateUsers=full + * and using the system service manager. */ + const char *a = procfs_file_alloca(ppid, "setgroups"); + const char *setgroups = allow_setgroups ? "allow" : "deny"; + r = write_string_file(a, setgroups, WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) + return log_debug_errno(r, "Failed to write '%s' to %s: %m", setgroups, a); + + /* First write the GID map */ + a = procfs_file_alloca(ppid, "gid_map"); + r = write_string_file(a, gid_map, WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) + return log_debug_errno(r, "Failed to write GID map to %s: %m", a); + + /* Then write the UID map */ + a = procfs_file_alloca(ppid, "uid_map"); + r = write_string_file(a, uid_map, WRITE_STRING_FILE_DISABLE_BUFFER); + if (r < 0) + return log_debug_errno(r, "Failed to write UID map to %s: %m", a); + + return 0; +} + static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogid, uid_t uid, gid_t gid, bool allow_setgroups) { _cleanup_free_ char *uid_map = NULL, *gid_map = NULL; _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;