From: Lennart Poettering Date: Thu, 31 Mar 2022 12:37:29 +0000 (+0200) Subject: pid1: add taint flag if uid/gid userns range too small X-Git-Tag: v251-rc2~226^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=63e8df046b40cdf7196462f41de4bca54882f7b2;p=thirdparty%2Fsystemd.git pid1: add taint flag if uid/gid userns range too small This will taint systemd if invoked in containers that do not have the full 16bit range of UIDs defined. we pretty much need uid root…nobody to be defined for a variety of purposes, hence let's add this taint flag. Of course taints are graceful, but it at least communicates the mess in some way... --- diff --git a/src/core/manager.c b/src/core/manager.c index 768977dc3a7..e92004edf33 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -82,6 +82,7 @@ #include "terminal-util.h" #include "time-util.h" #include "transaction.h" +#include "uid-range.h" #include "umask-util.h" #include "unit-name.h" #include "user-util.h" @@ -4350,16 +4351,34 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re return 0; } +static int short_uid_range(const char *path) { + _cleanup_free_ UidRange *p = NULL; + size_t n = 0; + int r; + + assert(path); + + /* Taint systemd if we the UID range assigned to this environment doesn't at least cover 0…65534, + * i.e. from root to nobody. */ + + r = uid_range_load_userns(&p, &n, path); + if (ERRNO_IS_NOT_SUPPORTED(r)) + return false; + if (r < 0) + return log_debug_errno(r, "Failed to load %s: %m", path); + + return !uid_range_covers(p, n, 0, 65535); +} + char *manager_taint_string(Manager *m) { _cleanup_free_ char *destination = NULL, *overflowuid = NULL, *overflowgid = NULL; struct utsname uts; char *buf, *e; int r; - /* Returns a "taint string", e.g. "local-hwclock:var-run-bad". - * Only things that are detected at runtime should be tagged - * here. For stuff that is set during compilation, emit a warning - * in the configuration phase. */ + /* Returns a "taint string", e.g. "local-hwclock:var-run-bad". Only things that are detected at + * runtime should be tagged here. For stuff that is set during compilation, emit a warning in the + * configuration phase. */ assert(m); @@ -4370,7 +4389,9 @@ char *manager_taint_string(Manager *m) { "var-run-bad:" "overflowuid-not-65534:" "overflowgid-not-65534:" - "old-kernel:")); + "old-kernel:" + "short-uid-range:" + "short-gid-range:")); if (!buf) return NULL; @@ -4396,7 +4417,6 @@ char *manager_taint_string(Manager *m) { r = read_one_line_file("/proc/sys/kernel/overflowuid", &overflowuid); if (r >= 0 && !streq(overflowuid, "65534")) e = stpcpy(e, "overflowuid-not-65534:"); - r = read_one_line_file("/proc/sys/kernel/overflowgid", &overflowgid); if (r >= 0 && !streq(overflowgid, "65534")) e = stpcpy(e, "overflowgid-not-65534:"); @@ -4405,6 +4425,11 @@ char *manager_taint_string(Manager *m) { if (strverscmp_improved(uts.release, KERNEL_BASELINE_VERSION) < 0) e = stpcpy(e, "old-kernel:"); + if (short_uid_range("/proc/self/uid_map") > 0) + e = stpcpy(e, "short-uid-range:"); + if (short_uid_range("/proc/self/gid_map") > 0) + e = stpcpy(e, "short-gid-range:"); + /* remove the last ':' */ if (e != buf) e[-1] = 0;