diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 18b16ecc0e5..68b15846292 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -2141,15 +2141,14 @@ int cg_kernel_controllers(Set **ret) { _cleanup_free_ char *controller = NULL; int enabled = 0; - errno = 0; if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) { + if (ferror(f)) + return -errno; + if (feof(f)) break; - if (ferror(f)) - return errno_or_else(EIO); - return -EBADMSG; } 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/fsck/fsck.c b/src/fsck/fsck.c index 000ed69667d..729209fc89d 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -177,7 +177,7 @@ static int process_progress(int fd, FILE* console) { else if (feof(f)) r = 0; else - r = log_warning_errno(SYNTHETIC_ERRNO(errno), "Failed to parse progress pipe data"); + r = log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse progress pipe data."); break; } diff --git a/src/machine/machine.c b/src/machine/machine.c index 44ff5c190bb..af8a88f26ca 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" @@ -658,7 +659,7 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) { uid_t uid_base, uid_shift, uid_range; gid_t gid_base, gid_shift, gid_range; _cleanup_fclose_ FILE *f = NULL; - int k, r; + int r; assert(m); assert(ret); @@ -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) @@ -722,13 +718,12 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) { /* Read the first line. There's at least one. */ errno = 0; - k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT "\n", &gid_base, &gid_shift, &gid_range); - if (k != 3) { - if (ferror(f)) - return errno_or_else(EIO); - + r = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT "\n", &gid_base, &gid_shift, &gid_range); + if (r == EOF) + return errno_or_else(ENOMSG); + assert(r >= 0); + if (r != 3) return -EBADMSG; - } /* If there's more than one line, then we don't support this file. */ r = safe_fgetc(f, NULL); @@ -757,6 +752,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 +774,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 +821,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 +841,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 +857,7 @@ static int machine_translate_uid_internal( if (ret_host_uid) *ret_host_uid = converted; + return 0; }