From 9587a355ff6ed05a92ba226cc2a37e113c1d106c Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 20 Aug 2026 15:30:31 +1000 Subject: util, pasta: Generalise [ug]id_map creation pasta_start_ns() creates UID and GID mappings for the user namespace in which the child process runs. We're going to want some more flexible variants of this, so move it into a more general helper function make_ugid_map() which will make a single user UID/GID mapping for the userns owned by a given PID. Signed-off-by: David Gibson Signed-off-by: Stefano Brivio --- pasta.c | 17 ++--------------- util.c | 39 +++++++++++++++++++++++++++++++++++++++ util.h | 2 ++ 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/pasta.c b/pasta.c index b998a9f..3abb9ba 100644 --- a/pasta.c +++ b/pasta.c @@ -260,21 +260,8 @@ void pasta_start_ns(struct ctx *c, uid_t uid, gid_t gid, bool config_idmaps, c->quiet = 1; /* Configure user and group mappings */ - if (config_idmaps) { - char uidmap[BUFSIZ], gidmap[BUFSIZ]; - - if (snprintf_check(uidmap, BUFSIZ, "0 %u 1", uid)) - die_perror("Can't build uidmap"); - - if (snprintf_check(gidmap, BUFSIZ, "0 %u 1", gid)) - die_perror("Can't build gidmap"); - - if (write_file("/proc/self/uid_map", uidmap) || - write_file("/proc/self/setgroups", "deny") || - write_file("/proc/self/gid_map", gidmap)) { - warn("Couldn't configure user mappings"); - } - } + if (config_idmaps) + make_ugid_map(0, uid, gid); if (argc == 0) { arg.exe = getenv("SHELL"); diff --git a/util.c b/util.c index 28c32e4..ec1d3d6 100644 --- a/util.c +++ b/util.c @@ -1113,3 +1113,42 @@ long clamped_scale(long x, long y, long lo, long hi, long f) return x - (x * (y - lo) / (hi - lo)) * (100 - f) / 100; } + +/** + * make_ugid_map() - Create userns UID & GID mappings + * @pid: PID of process owning the userns, or 0 for self + * @uid: Parent UID to map to 0 within userns + * @gid: Parent GID to map to 0 within userns + */ +void make_ugid_map(pid_t pid, uid_t uid, gid_t gid) +{ + char setgroups_path[PATH_MAX] = "/proc/self/setgroups"; + char uidmap_path[PATH_MAX] = "/proc/self/uid_map"; + char gidmap_path[PATH_MAX] = "/proc/self/gid_map"; + char uidmap[BUFSIZ], gidmap[BUFSIZ]; + + if (pid) { + if (snprintf_check(uidmap_path, sizeof(uidmap_path), + "/proc/%u/uid_map", pid)) + die_perror("Can't build uidmap path"); + + if (snprintf_check(gidmap_path, sizeof(gidmap_path), + "/proc/%u/gid_map", pid)) + die_perror("Can't build gidmap path"); + + if (snprintf_check(setgroups_path, sizeof(setgroups_path), + "/proc/%u/setgroups", pid)) + die_perror("Can't build setgroups path"); + } + + if (snprintf_check(uidmap, sizeof(uidmap), "0 %u 1", uid)) + die_perror("Can't build uidmap"); + + if (snprintf_check(gidmap, BUFSIZ, "0 %u 1", gid)) + die_perror("Can't build gidmap"); + + if (write_file(uidmap_path, uidmap) || + write_file(setgroups_path, "deny") || + write_file(gidmap_path, gidmap)) + die("Couldn't configure user mappings"); +} diff --git a/util.h b/util.h index 2435f53..ec2d9ac 100644 --- a/util.h +++ b/util.h @@ -290,4 +290,6 @@ static inline int wrap_getsockname(int sockfd, struct sockaddr *addr, #define PASST_MAXDNAME 254 /* 253 (RFC 1035) + 1 (the terminator) */ void encode_domain_name(char *buf, const char *domain_name); +void make_ugid_map(pid_t pid, uid_t uid, gid_t gid); + #endif /* UTIL_H */ -- cgit v1.2.3