diff options
| author | David Gibson <david@gibson.dropbear.id.au> | 2026-08-20 15:30:31 +1000 |
|---|---|---|
| committer | Stefano Brivio <sbrivio@redhat.com> | 2026-09-08 16:00:19 +0200 |
| commit | 9587a355ff6ed05a92ba226cc2a37e113c1d106c (patch) | |
| tree | 05da0c3a6201ca98af4a35f7d6e74f9e80bda603 | |
| parent | 5b4bdc8c0362c1e0926a8f0eeb6e63f89c0ec7d5 (diff) | |
| download | passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar.gz passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar.bz2 passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar.lz passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar.xz passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.tar.zst passt-9587a355ff6ed05a92ba226cc2a37e113c1d106c.zip | |
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 <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
| -rw-r--r-- | pasta.c | 17 | ||||
| -rw-r--r-- | util.c | 39 | ||||
| -rw-r--r-- | util.h | 2 |
3 files changed, 43 insertions, 15 deletions
@@ -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"); @@ -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"); +} @@ -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 */ |
