From: Mike Yuan Date: Thu, 14 Dec 2023 15:55:43 +0000 (+0800) Subject: basic/uid-range: add uid_map_read_one helper X-Git-Tag: v256-rc1~1478^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7312c422f01744cee1420acf04c24140e95440e3;p=thirdparty%2Fsystemd.git basic/uid-range: add uid_map_read_one helper --- diff --git a/src/basic/uid-range.c b/src/basic/uid-range.c index 84635992761..d933d9fa5c1 100644 --- a/src/basic/uid-range.c +++ b/src/basic/uid-range.c @@ -180,6 +180,30 @@ bool uid_range_covers(const UidRange *range, uid_t start, uid_t nr) { return false; } +int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range) { + uid_t uid_base, uid_shift, uid_range; + int r; + + assert(f); + assert(ret_base); + assert(ret_shift); + assert(ret_range); + + errno = 0; + r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range); + if (r == EOF) + return errno_or_else(ENOMSG); + assert(r >= 0); + if (r != 3) + return -EBADMSG; + + *ret_base = uid_base; + *ret_shift = uid_shift; + *ret_range = uid_range; + + return 0; +} + int uid_range_load_userns(UidRange **ret, const char *path) { _cleanup_(uid_range_freep) UidRange *range = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -212,18 +236,12 @@ int uid_range_load_userns(UidRange **ret, const char *path) { for (;;) { uid_t uid_base, uid_shift, uid_range; - int k; - - errno = 0; - k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range); - if (k == EOF) { - if (ferror(f)) - return errno_or_else(EIO); + r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range); + if (r == -ENOMSG) break; - } - if (k != 3) - return -EBADMSG; + if (r < 0) + return r; r = uid_range_add_internal(&range, uid_base, uid_range, /* coalesce = */ false); if (r < 0) diff --git a/src/basic/uid-range.h b/src/basic/uid-range.h index 461a5117373..bfe78926698 100644 --- a/src/basic/uid-range.h +++ b/src/basic/uid-range.h @@ -31,4 +31,6 @@ static inline bool uid_range_contains(const UidRange *range, uid_t uid) { return uid_range_covers(range, uid, 1); } +int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range); + int uid_range_load_userns(UidRange **ret, const char *path); diff --git a/src/basic/virt.c b/src/basic/virt.c index a0b6fbcd658..09aebabcd5e 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -21,6 +21,7 @@ #include "stat-util.h" #include "string-table.h" #include "string-util.h" +#include "uid-range.h" #include "virt.h" enum { @@ -814,7 +815,7 @@ Virtualization detect_virtualization(void) { static int userns_has_mapping(const char *name) { _cleanup_fclose_ FILE *f = NULL; - uid_t a, b, c; + uid_t base, shift, range; int r; f = fopen(name, "re"); @@ -823,26 +824,22 @@ static int userns_has_mapping(const char *name) { return errno == ENOENT ? false : -errno; } - errno = 0; - r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &a, &b, &c); - if (r == EOF) { - if (ferror(f)) - return log_debug_errno(errno_or_else(EIO), "Failed to read %s: %m", name); - - log_debug("%s is empty, we're in an uninitialized user namespace", name); + r = uid_map_read_one(f, &base, &shift, &range); + if (r == -ENOMSG) { + log_debug("%s is empty, we're in an uninitialized user namespace.", name); return true; } - if (r != 3) - return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse %s: %m", name); + if (r < 0) + return log_debug_errno(r, "Failed to read %s: %m", name); - if (a == 0 && b == 0 && c == UINT32_MAX) { + if (base == 0 && shift == 0 && range == UINT32_MAX) { /* The kernel calls mappings_overlap() and does not allow overlaps */ log_debug("%s has a full 1:1 mapping", name); return false; } /* Anything else implies that we are in a user namespace */ - log_debug("Mapping found in %s, we're in a user namespace", name); + log_debug("Mapping found in %s, we're in a user namespace.", name); return true; } diff --git a/src/machine/machine.c b/src/machine/machine.c index 44ff5c190bb..1939843b643 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -32,6 +32,7 @@ #include "string-table.h" #include "terminal-util.h" #include "tmpfile-util.h" +#include "uid-range.h" #include "unit-name.h" #include "user-util.h" @@ -690,14 +691,9 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) { } /* Read the first line. There's at least one. */ - errno = 0; - k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range); - if (k != 3) { - if (ferror(f)) - return errno_or_else(EIO); - - return -EBADMSG; - } + r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range); + if (r < 0) + return r; /* Not a mapping starting at 0? Then it's a complex mapping we can't expose here. */ if (uid_base != 0) @@ -757,6 +753,7 @@ static int machine_owns_uid_internal( _cleanup_fclose_ FILE *f = NULL; const char *p; + int r; /* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */ assert_cc(sizeof(uid_t) == sizeof(gid_t)); @@ -778,18 +775,12 @@ static int machine_owns_uid_internal( for (;;) { uid_t uid_base, uid_shift, uid_range, converted; - int k; - errno = 0; - k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range); - if (k < 0 && feof(f)) + r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range); + if (r == -ENOMSG) break; - if (k != 3) { - if (ferror(f)) - return errno_or_else(EIO); - - return -EIO; - } + if (r < 0) + return r; /* The private user namespace is disabled, ignoring. */ if (uid_shift == 0) @@ -831,6 +822,7 @@ static int machine_translate_uid_internal( _cleanup_fclose_ FILE *f = NULL; const char *p; + int r; /* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */ assert_cc(sizeof(uid_t) == sizeof(gid_t)); @@ -850,18 +842,12 @@ static int machine_translate_uid_internal( for (;;) { uid_t uid_base, uid_shift, uid_range, converted; - int k; - errno = 0; - k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range); - if (k < 0 && feof(f)) + r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range); + if (r == -ENOMSG) break; - if (k != 3) { - if (ferror(f)) - return errno_or_else(EIO); - - return -EIO; - } + if (r < 0) + return r; if (uid < uid_base || uid >= uid_base + uid_range) continue; @@ -872,6 +858,7 @@ static int machine_translate_uid_internal( if (ret_host_uid) *ret_host_uid = converted; + return 0; }