aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-08-20 15:30:31 +1000
committerStefano Brivio <sbrivio@redhat.com>2026-09-08 16:00:19 +0200
commit9587a355ff6ed05a92ba226cc2a37e113c1d106c (patch)
tree05da0c3a6201ca98af4a35f7d6e74f9e80bda603
parent5b4bdc8c0362c1e0926a8f0eeb6e63f89c0ec7d5 (diff)
downloadpasst-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.c17
-rw-r--r--util.c39
-rw-r--r--util.h2
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 */