diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-16 10:52:00 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-16 20:56:58 +0900 |
commit | 8dcc66cefc8ab489568c737adcba960756d76a3c (patch) | |
tree | 323d37effe0bb0f2a752dfd2007e8bcdc0f691ea /src | |
parent | 6cc6cd9289d9bfc4eb947e68b060d6bb9d284f63 (diff) | |
download | systemd-8dcc66cefc8ab489568c737adcba960756d76a3c.tar.gz |
uid-range: tie up number and array of uid range entries
This renames UidRange -> UidRangeEntry, and reintroduces UidRange which
contains the array of UidRangeEntry and its size.
No fucntional changes, just refactoring.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/uid-range.c | 115 | ||||
-rw-r--r-- | src/basic/uid-range.h | 30 | ||||
-rw-r--r-- | src/core/manager.c | 14 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-monitor.c | 11 | ||||
-rw-r--r-- | src/sysusers/sysusers.c | 15 | ||||
-rw-r--r-- | src/test/test-uid-range.c | 172 | ||||
-rw-r--r-- | src/userdb/userdbctl.c | 48 |
7 files changed, 211 insertions, 194 deletions
diff --git a/src/basic/uid-range.c b/src/basic/uid-range.c index fbc764673c..8463599276 100644 --- a/src/basic/uid-range.c +++ b/src/basic/uid-range.c @@ -15,14 +15,22 @@ #include "uid-range.h" #include "user-util.h" -static bool uid_range_intersect(const UidRange *a, const UidRange *b) { +UidRange *uid_range_free(UidRange *range) { + if (!range) + return NULL; + + free(range->entries); + return mfree(range); +} + +static bool uid_range_entry_intersect(const UidRangeEntry *a, const UidRangeEntry *b) { assert(a); assert(b); return a->start <= b->start + b->nr && a->start + a->nr >= b->start; } -static int uid_range_compare(const UidRange *a, const UidRange *b) { +static int uid_range_entry_compare(const UidRangeEntry *a, const UidRangeEntry *b) { int r; assert(a); @@ -35,23 +43,22 @@ static int uid_range_compare(const UidRange *a, const UidRange *b) { return CMP(a->nr, b->nr); } -static void uid_range_coalesce(UidRange **p, size_t *n) { - assert(p); - assert(n); +static void uid_range_coalesce(UidRange *range) { + assert(range); - if (*n <= 1) + if (range->n_entries <= 0) return; - typesafe_qsort(*p, *n, uid_range_compare); + typesafe_qsort(range->entries, range->n_entries, uid_range_entry_compare); - for (size_t i = 0; i < *n; i++) { - UidRange *x = (*p) + i; + for (size_t i = 0; i < range->n_entries; i++) { + UidRangeEntry *x = range->entries + i; - for (size_t j = i + 1; j < *n; j++) { - UidRange *y = (*p)+j; + for (size_t j = i + 1; j < range->n_entries; j++) { + UidRangeEntry *y = range->entries + j; uid_t begin, end; - if (!uid_range_intersect(x, y)) + if (!uid_range_entry_intersect(x, y)) break; begin = MIN(x->start, y->start); @@ -60,18 +67,20 @@ static void uid_range_coalesce(UidRange **p, size_t *n) { x->start = begin; x->nr = end - begin; - if (*n > j+1) - memmove(y, y+1, sizeof(UidRange) * (*n - j -1)); + if (range->n_entries > j + 1) + memmove(y, y + 1, sizeof(UidRangeEntry) * (range->n_entries - j - 1)); - (*n)--; + range->n_entries--; j--; } } } -int uid_range_add_internal(UidRange **p, size_t *n, uid_t start, uid_t nr, bool coalesce) { - assert(p); - assert(n); +int uid_range_add_internal(UidRange **range, uid_t start, uid_t nr, bool coalesce) { + _cleanup_(uid_range_freep) UidRange *range_new = NULL; + UidRange *p; + + assert(range); if (nr <= 0) return 0; @@ -79,39 +88,51 @@ int uid_range_add_internal(UidRange **p, size_t *n, uid_t start, uid_t nr, bool if (start > UINT32_MAX - nr) /* overflow check */ return -ERANGE; - if (!GREEDY_REALLOC(*p, *n + 1)) + if (*range) + p = *range; + else { + range_new = new0(UidRange, 1); + if (!range_new) + return -ENOMEM; + + p = range_new; + } + + if (!GREEDY_REALLOC(p->entries, p->n_entries + 1)) return -ENOMEM; - (*p)[(*n)++] = (UidRange) { + p->entries[p->n_entries++] = (UidRangeEntry) { .start = start, .nr = nr, }; if (coalesce) - uid_range_coalesce(p, n); + uid_range_coalesce(p); + + TAKE_PTR(range_new); + *range = p; - return *n; + return 0; } -int uid_range_add_str(UidRange **p, size_t *n, const char *s) { +int uid_range_add_str(UidRange **range, const char *s) { uid_t start, end; int r; - assert(p); - assert(n); + assert(range); assert(s); r = parse_uid_range(s, &start, &end); if (r < 0) return r; - return uid_range_add(p, n, start, end - start + 1); + return uid_range_add_internal(range, start, end - start + 1, /* coalesce = */ true); } -int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid) { +int uid_range_next_lower(const UidRange *range, uid_t *uid) { uid_t closest = UID_INVALID, candidate; - assert(p); + assert(range); assert(uid); if (*uid == 0) @@ -119,11 +140,11 @@ int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid) { candidate = *uid - 1; - for (size_t i = 0; i < n; i++) { + for (size_t i = 0; i < range->n_entries; i++) { uid_t begin, end; - begin = p[i].start; - end = p[i].start + p[i].nr - 1; + begin = range->entries[i].start; + end = range->entries[i].start + range->entries[i].nr - 1; if (candidate >= begin && candidate <= end) { *uid = candidate; @@ -141,26 +162,27 @@ int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid) { return 1; } -bool uid_range_covers(const UidRange *p, size_t n, uid_t start, uid_t nr) { - assert(p || n == 0); - +bool uid_range_covers(const UidRange *range, uid_t start, uid_t nr) { if (nr == 0) /* empty range? always covered... */ return true; if (start > UINT32_MAX - nr) /* range overflows? definitely not covered... */ return false; - for (size_t i = 0; i < n; i++) - if (start >= p[i].start && start + nr <= p[i].start + p[i].nr) + if (!range) + return false; + + for (size_t i = 0; i < range->n_entries; i++) + if (start >= range->entries[i].start && + start + nr <= range->entries[i].start + range->entries[i].nr) return true; return false; } -int uid_range_load_userns(UidRange **p, size_t *n, const char *path) { - _cleanup_free_ UidRange *q = NULL; +int uid_range_load_userns(UidRange **ret, const char *path) { + _cleanup_(uid_range_freep) UidRange *range = NULL; _cleanup_fclose_ FILE *f = NULL; - size_t m = 0; int r; /* If 'path' is NULL loads the UID range of the userns namespace we run. Otherwise load the data from @@ -169,8 +191,7 @@ int uid_range_load_userns(UidRange **p, size_t *n, const char *path) { * * To simplify things this will modify the passed array in case of later failure. */ - assert(p); - assert(n); + assert(ret); if (!path) path = "/proc/self/uid_map"; @@ -185,6 +206,10 @@ int uid_range_load_userns(UidRange **p, size_t *n, const char *path) { return r; } + range = new0(UidRange, 1); + if (!range) + return -ENOMEM; + for (;;) { uid_t uid_base, uid_shift, uid_range; int k; @@ -200,15 +225,13 @@ int uid_range_load_userns(UidRange **p, size_t *n, const char *path) { if (k != 3) return -EBADMSG; - r = uid_range_add_internal(&q, &m, uid_base, uid_range, /* coalesce = */ false); + r = uid_range_add_internal(&range, uid_base, uid_range, /* coalesce = */ false); if (r < 0) return r; } - uid_range_coalesce(&q, &m); - - *p = TAKE_PTR(q); - *n = m; + uid_range_coalesce(range); + *ret = TAKE_PTR(range); return 0; } diff --git a/src/basic/uid-range.h b/src/basic/uid-range.h index 7e238409d1..461a511737 100644 --- a/src/basic/uid-range.h +++ b/src/basic/uid-range.h @@ -4,21 +4,31 @@ #include <stdbool.h> #include <sys/types.h> -typedef struct UidRange { +#include "macro.h" + +typedef struct UidRangeEntry { uid_t start, nr; +} UidRangeEntry; + +typedef struct UidRange { + UidRangeEntry *entries; + size_t n_entries; } UidRange; -int uid_range_add_internal(UidRange **p, size_t *n, uid_t start, uid_t nr, bool coalesce); -static inline int uid_range_add(UidRange **p, size_t *n, uid_t start, uid_t nr) { - return uid_range_add_internal(p, n, start, nr, true); +UidRange *uid_range_free(UidRange *range); +DEFINE_TRIVIAL_CLEANUP_FUNC(UidRange*, uid_range_free); + +int uid_range_add_internal(UidRange **range, uid_t start, uid_t nr, bool coalesce); +static inline int uid_range_add(UidRange **range, uid_t start, uid_t nr) { + return uid_range_add_internal(range, start, nr, true); } -int uid_range_add_str(UidRange **p, size_t *n, const char *s); +int uid_range_add_str(UidRange **range, const char *s); -int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid); -bool uid_range_covers(const UidRange *p, size_t n, uid_t start, uid_t nr); +int uid_range_next_lower(const UidRange *range, uid_t *uid); -static inline bool uid_range_contains(const UidRange *p, size_t n, uid_t uid) { - return uid_range_covers(p, n, uid, 1); +bool uid_range_covers(const UidRange *range, uid_t start, uid_t nr); +static inline bool uid_range_contains(const UidRange *range, uid_t uid) { + return uid_range_covers(range, uid, 1); } -int uid_range_load_userns(UidRange **p, size_t *n, const char *path); +int uid_range_load_userns(UidRange **ret, const char *path); diff --git a/src/core/manager.c b/src/core/manager.c index cc89ae3f9c..90e126840a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -4457,8 +4457,7 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re } static int short_uid_range(const char *path) { - _cleanup_free_ UidRange *p = NULL; - size_t n = 0; + _cleanup_(uid_range_freep) UidRange *p = NULL; int r; assert(path); @@ -4466,13 +4465,14 @@ static int short_uid_range(const char *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) + r = uid_range_load_userns(&p, path); + if (r < 0) { + if (ERRNO_IS_NOT_SUPPORTED(r)) + return false; return log_debug_errno(r, "Failed to load %s: %m", path); + } - return !uid_range_covers(p, n, 0, 65535); + return !uid_range_covers(p, 0, 65535); } char* manager_taint_string(const Manager *m) { diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c index 072c6b94d3..48f425396a 100644 --- a/src/libsystemd/sd-device/device-monitor.c +++ b/src/libsystemd/sd-device/device-monitor.c @@ -48,7 +48,6 @@ struct sd_device_monitor { bool bound; UidRange *mapped_userns_uid_range; - size_t n_uid_range; Hashmap *subsystem_filter; Set *tag_filter; @@ -174,7 +173,6 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group, .bound = fd >= 0, .snl.nl.nl_family = AF_NETLINK, .snl.nl.nl_groups = group, - .n_uid_range = SIZE_MAX, }; if (fd >= 0) { @@ -376,7 +374,7 @@ static sd_device_monitor *device_monitor_free(sd_device_monitor *m) { (void) sd_device_monitor_detach_event(m); - free(m->mapped_userns_uid_range); + uid_range_free(m->mapped_userns_uid_range); free(m->description); hashmap_free(m->subsystem_filter); set_free(m->tag_filter); @@ -468,15 +466,14 @@ static bool check_sender_uid(sd_device_monitor *m, uid_t uid) { if (uid == getuid() || uid == geteuid()) return true; - if (m->n_uid_range == SIZE_MAX) { - m->n_uid_range = 0; - r = uid_range_load_userns(&m->mapped_userns_uid_range, &m->n_uid_range, NULL); + if (!m->mapped_userns_uid_range) { + r = uid_range_load_userns(&m->mapped_userns_uid_range, NULL); if (r < 0) log_monitor_errno(m, r, "Failed to load UID ranges mapped to the current user namespace, ignoring: %m"); } /* Trust messages come from outside of the current user namespace. */ - if (m->n_uid_range != SIZE_MAX && !uid_range_contains(m->mapped_userns_uid_range, m->n_uid_range, uid)) + if (!uid_range_contains(m->mapped_userns_uid_range, uid)) return true; /* Otherwise, refuse messages. */ diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 491e4a0ea2..6f66f087cb 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -107,7 +107,6 @@ static Set *database_users = NULL, *database_groups = NULL; static uid_t search_uid = UID_INVALID; static UidRange *uid_range = NULL; -static size_t n_uid_range = 0; static UGIDAllocationRange login_defs = {}; static bool login_defs_need_warning = false; @@ -123,7 +122,7 @@ STATIC_DESTRUCTOR_REGISTER(database_users, set_free_freep); STATIC_DESTRUCTOR_REGISTER(database_by_gid, hashmap_freep); STATIC_DESTRUCTOR_REGISTER(database_by_groupname, hashmap_freep); STATIC_DESTRUCTOR_REGISTER(database_groups, set_free_freep); -STATIC_DESTRUCTOR_REGISTER(uid_range, freep); +STATIC_DESTRUCTOR_REGISTER(uid_range, uid_range_freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); @@ -1113,7 +1112,7 @@ static int add_user(Item *i) { if (read_id_from_file(i, &c, NULL) > 0) { - if (c <= 0 || !uid_range_contains(uid_range, n_uid_range, c)) + if (c <= 0 || !uid_range_contains(uid_range, c)) log_debug("User ID " UID_FMT " of file not suitable for %s.", c, i->name); else { r = uid_is_ok(c, i->name, true); @@ -1144,7 +1143,7 @@ static int add_user(Item *i) { maybe_emit_login_defs_warning(); for (;;) { - r = uid_range_next_lower(uid_range, n_uid_range, &search_uid); + r = uid_range_next_lower(uid_range, &search_uid); if (r < 0) return log_error_errno(r, "No free user ID available for %s.", i->name); @@ -1297,7 +1296,7 @@ static int add_group(Item *i) { if (read_id_from_file(i, NULL, &c) > 0) { - if (c <= 0 || !uid_range_contains(uid_range, n_uid_range, c)) + if (c <= 0 || !uid_range_contains(uid_range, c)) log_debug("Group ID " GID_FMT " of file not suitable for %s.", c, i->name); else { r = gid_is_ok(c, true); @@ -1318,7 +1317,7 @@ static int add_group(Item *i) { for (;;) { /* We look for new GIDs in the UID pool! */ - r = uid_range_next_lower(uid_range, n_uid_range, &search_uid); + r = uid_range_next_lower(uid_range, &search_uid); if (r < 0) return log_error_errno(r, "No free group ID available for %s.", i->name); @@ -1668,7 +1667,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { action[0], description ? "GECOS" : home ? "home directory" : "login shell"); - r = uid_range_add_str(&uid_range, &n_uid_range, resolved_id); + r = uid_range_add_str(&uid_range, resolved_id); if (r < 0) return log_syntax(NULL, LOG_ERR, fname, line, SYNTHETIC_ERRNO(EINVAL), "Invalid UID range %s.", resolved_id); @@ -2169,7 +2168,7 @@ static int run(int argc, char *argv[]) { uid_t begin = login_defs.system_alloc_uid_min, end = MIN3((uid_t) SYSTEM_UID_MAX, login_defs.system_uid_max, login_defs.system_gid_max); if (begin < end) { - r = uid_range_add(&uid_range, &n_uid_range, begin, end - begin + 1); + r = uid_range_add(&uid_range, begin, end - begin + 1); if (r < 0) return log_oom(); } diff --git a/src/test/test-uid-range.c b/src/test/test-uid-range.c index be8530bdd8..2ed557dd13 100644 --- a/src/test/test-uid-range.c +++ b/src/test/test-uid-range.c @@ -15,105 +15,104 @@ #include "virt.h" TEST(uid_range) { - _cleanup_free_ UidRange *p = NULL; - size_t n = 0; + _cleanup_(uid_range_freep) UidRange *p = NULL; uid_t search; - assert_se(uid_range_covers(p, n, 0, 0)); - assert_se(!uid_range_covers(p, n, 0, 1)); - assert_se(!uid_range_covers(p, n, 100, UINT32_MAX)); - - assert_se(uid_range_add_str(&p, &n, "500-999") >= 0); - assert_se(n == 1); - assert_se(p[0].start == 500); - assert_se(p[0].nr == 500); - - assert_se(!uid_range_contains(p, n, 499)); - assert_se(uid_range_contains(p, n, 500)); - assert_se(uid_range_contains(p, n, 999)); - assert_se(!uid_range_contains(p, n, 1000)); - - assert_se(!uid_range_covers(p, n, 100, 150)); - assert_se(!uid_range_covers(p, n, 400, 200)); - assert_se(!uid_range_covers(p, n, 499, 1)); - assert_se(uid_range_covers(p, n, 500, 1)); - assert_se(uid_range_covers(p, n, 501, 10)); - assert_se(uid_range_covers(p, n, 999, 1)); - assert_se(!uid_range_covers(p, n, 999, 2)); - assert_se(!uid_range_covers(p, n, 1000, 1)); - assert_se(!uid_range_covers(p, n, 1000, 100)); - assert_se(!uid_range_covers(p, n, 1001, 100)); + assert_se(uid_range_covers(p, 0, 0)); + assert_se(!uid_range_covers(p, 0, 1)); + assert_se(!uid_range_covers(p, 100, UINT32_MAX)); + + assert_se(uid_range_add_str(&p, "500-999") >= 0); + assert_se(p); + assert_se(p->n_entries == 1); + assert_se(p->entries[0].start == 500); + assert_se(p->entries[0].nr == 500); + + assert_se(!uid_range_contains(p, 499)); + assert_se(uid_range_contains(p, 500)); + assert_se(uid_range_contains(p, 999)); + assert_se(!uid_range_contains(p, 1000)); + + assert_se(!uid_range_covers(p, 100, 150)); + assert_se(!uid_range_covers(p, 400, 200)); + assert_se(!uid_range_covers(p, 499, 1)); + assert_se(uid_range_covers(p, 500, 1)); + assert_se(uid_range_covers(p, 501, 10)); + assert_se(uid_range_covers(p, 999, 1)); + assert_se(!uid_range_covers(p, 999, 2)); + assert_se(!uid_range_covers(p, 1000, 1)); + assert_se(!uid_range_covers(p, 1000, 100)); + assert_se(!uid_range_covers(p, 1001, 100)); search = UID_INVALID; - assert_se(uid_range_next_lower(p, n, &search)); + assert_se(uid_range_next_lower(p, &search)); assert_se(search == 999); - assert_se(uid_range_next_lower(p, n, &search)); + assert_se(uid_range_next_lower(p, &search)); assert_se(search == 998); search = 501; - assert_se(uid_range_next_lower(p, n, &search)); + assert_se(uid_range_next_lower(p, &search)); assert_se(search == 500); - assert_se(uid_range_next_lower(p, n, &search) == -EBUSY); - - assert_se(uid_range_add_str(&p, &n, "1000") >= 0); - assert_se(n == 1); - assert_se(p[0].start == 500); - assert_se(p[0].nr == 501); - - assert_se(uid_range_add_str(&p, &n, "30-40") >= 0); - assert_se(n == 2); - assert_se(p[0].start == 30); - assert_se(p[0].nr == 11); - assert_se(p[1].start == 500); - assert_se(p[1].nr == 501); - - assert_se(uid_range_add_str(&p, &n, "60-70") >= 0); - assert_se(n == 3); - assert_se(p[0].start == 30); - assert_se(p[0].nr == 11); - assert_se(p[1].start == 60); - assert_se(p[1].nr == 11); - assert_se(p[2].start == 500); - assert_se(p[2].nr == 501); - - assert_se(uid_range_add_str(&p, &n, "20-2000") >= 0); - assert_se(n == 1); - assert_se(p[0].start == 20); - assert_se(p[0].nr == 1981); - - assert_se(uid_range_add_str(&p, &n, "2002") >= 0); - assert_se(n == 2); - assert_se(p[0].start == 20); - assert_se(p[0].nr == 1981); - assert_se(p[1].start == 2002); - assert_se(p[1].nr == 1); - - assert_se(uid_range_add_str(&p, &n, "2001") >= 0); - assert_se(n == 1); - assert_se(p[0].start == 20); - assert_se(p[0].nr == 1983); + assert_se(uid_range_next_lower(p, &search) == -EBUSY); + + assert_se(uid_range_add_str(&p, "1000") >= 0); + assert_se(p->n_entries == 1); + assert_se(p->entries[0].start == 500); + assert_se(p->entries[0].nr == 501); + + assert_se(uid_range_add_str(&p, "30-40") >= 0); + assert_se(p->n_entries == 2); + assert_se(p->entries[0].start == 30); + assert_se(p->entries[0].nr == 11); + assert_se(p->entries[1].start == 500); + assert_se(p->entries[1].nr == 501); + + assert_se(uid_range_add_str(&p, "60-70") >= 0); + assert_se(p->n_entries == 3); + assert_se(p->entries[0].start == 30); + assert_se(p->entries[0].nr == 11); + assert_se(p->entries[1].start == 60); + assert_se(p->entries[1].nr == 11); + assert_se(p->entries[2].start == 500); + assert_se(p->entries[2].nr == 501); + + assert_se(uid_range_add_str(&p, "20-2000") >= 0); + assert_se(p->n_entries == 1); + assert_se(p->entries[0].start == 20); + assert_se(p->entries[0].nr == 1981); + + assert_se(uid_range_add_str(&p, "2002") >= 0); + assert_se(p->n_entries == 2); + assert_se(p->entries[0].start == 20); + assert_se(p->entries[0].nr == 1981); + assert_se(p->entries[1].start == 2002); + assert_se(p->entries[1].nr == 1); + + assert_se(uid_range_add_str(&p, "2001") >= 0); + assert_se(p->n_entries == 1); + assert_se(p->entries[0].start == 20); + assert_se(p->entries[0].nr == 1983); } TEST(load_userns) { + _cleanup_(uid_range_freep) UidRange *p = NULL; _cleanup_(unlink_and_freep) char *fn = NULL; - _cleanup_free_ UidRange *p = NULL; _cleanup_fclose_ FILE *f = NULL; - size_t n = 0; int r; - r = uid_range_load_userns(&p, &n, NULL); - if (ERRNO_IS_NOT_SUPPORTED(r)) + r = uid_range_load_userns(&p, NULL); + if (r < 0 && ERRNO_IS_NOT_SUPPORTED(r)) return; assert_se(r >= 0); - assert_se(uid_range_contains(p, n, getuid())); + assert_se(uid_range_contains(p, getuid())); r = running_in_userns(); if (r == 0) { - assert_se(n == 1); - assert_se(p[0].start == 0); - assert_se(p[0].nr == UINT32_MAX); + assert_se(p->n_entries == 1); + assert_se(p->entries[0].start == 0); + assert_se(p->entries[0].nr == UINT32_MAX); - assert_se(uid_range_covers(p, n, 0, UINT32_MAX)); + assert_se(uid_range_covers(p, 0, UINT32_MAX)); } assert_se(fopen_temporary(NULL, &f, &fn) >= 0); @@ -121,19 +120,18 @@ TEST(load_userns) { "100 0 20\n", f); assert_se(fflush_and_check(f) >= 0); - p = mfree(p); - n = 0; + p = uid_range_free(p); - assert_se(uid_range_load_userns(&p, &n, fn) >= 0); + assert_se(uid_range_load_userns(&p, fn) >= 0); - assert_se(uid_range_contains(p, n, 0)); - assert_se(uid_range_contains(p, n, 19)); - assert_se(!uid_range_contains(p, n, 20)); + assert_se(uid_range_contains(p, 0)); + assert_se(uid_range_contains(p, 19)); + assert_se(!uid_range_contains(p, 20)); - assert_se(!uid_range_contains(p, n, 99)); - assert_se(uid_range_contains(p, n, 100)); - assert_se(uid_range_contains(p, n, 119)); - assert_se(!uid_range_contains(p, n, 120)); + assert_se(!uid_range_contains(p, 99)); + assert_se(uid_range_contains(p, 100)); + assert_se(uid_range_contains(p, 119)); + assert_se(!uid_range_contains(p, 120)); } DEFINE_TEST_MAIN(LOG_DEBUG); diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c index 362c29585f..5e9bce3bae 100644 --- a/src/userdb/userdbctl.c +++ b/src/userdb/userdbctl.c @@ -168,19 +168,15 @@ static const struct { }, }; -static int table_add_uid_boundaries( - Table *table, - const UidRange *p, - size_t n) { +static int table_add_uid_boundaries(Table *table, const UidRange *p) { int r; assert(table); - assert(p || n == 0); for (size_t i = 0; i < ELEMENTSOF(uid_range_table); i++) { _cleanup_free_ char *name = NULL, *comment = NULL; - if (!uid_range_covers(p, n, uid_range_table[i].first, uid_range_table[i].last - uid_range_table[i].first + 1)) + if (!uid_range_covers(p, uid_range_table[i].first, uid_range_table[i].last - uid_range_table[i].first + 1)) continue; name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), @@ -305,31 +301,31 @@ static int add_unavailable_uid(Table *table, uid_t start, uid_t end) { static int table_add_uid_map( Table *table, const UidRange *p, - size_t n, int (*add_unavailable)(Table *t, uid_t start, uid_t end)) { uid_t focus = 0; int n_added = 0, r; assert(table); - assert(p || n == 0); assert(add_unavailable); - for (size_t i = 0; i < n; i++) { - if (focus < p[i].start) { - r = add_unavailable(table, focus, p[i].start-1); + for (size_t i = 0; p && i < p->n_entries; i++) { + UidRangeEntry *x = p->entries + i; + + if (focus < x->start) { + r = add_unavailable(table, focus, x->start-1); if (r < 0) return r; n_added += r; } - if (p[i].start > UINT32_MAX - p[i].nr) { /* overflow check */ + if (x->start > UINT32_MAX - x->nr) { /* overflow check */ focus = UINT32_MAX; break; } - focus = p[i].start + p[i].nr; + focus = x->start + x->nr; } if (focus < UINT32_MAX-1) { @@ -428,19 +424,18 @@ static int display_user(int argc, char *argv[], void *userdata) { } if (table) { - _cleanup_free_ UidRange *uid_range = NULL; + _cleanup_(uid_range_freep) UidRange *uid_range = NULL; int boundary_lines, uid_map_lines; - size_t n_uid_range = 0; - r = uid_range_load_userns(&uid_range, &n_uid_range, "/proc/self/uid_map"); + r = uid_range_load_userns(&uid_range, "/proc/self/uid_map"); if (r < 0) log_debug_errno(r, "Failed to load /proc/self/uid_map, ignoring: %m"); - boundary_lines = table_add_uid_boundaries(table, uid_range, n_uid_range); + boundary_lines = table_add_uid_boundaries(table, uid_range); if (boundary_lines < 0) return boundary_lines; - uid_map_lines = table_add_uid_map(table, uid_range, n_uid_range, add_unavailable_uid); + uid_map_lines = table_add_uid_map(table, uid_range, add_unavailable_uid); if (uid_map_lines < 0) return uid_map_lines; @@ -530,19 +525,15 @@ static int show_group(GroupRecord *gr, Table *table) { return 0; } -static int table_add_gid_boundaries( - Table *table, - const UidRange *p, - size_t n) { +static int table_add_gid_boundaries(Table *table, const UidRange *p) { int r; assert(table); - assert(p || n == 0); for (size_t i = 0; i < ELEMENTSOF(uid_range_table); i++) { _cleanup_free_ char *name = NULL, *comment = NULL; - if (!uid_range_covers(p, n, uid_range_table[i].first, uid_range_table[i].last)) + if (!uid_range_covers(p, uid_range_table[i].first, uid_range_table[i].last)) continue; name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), @@ -736,19 +727,18 @@ static int display_group(int argc, char *argv[], void *userdata) { } if (table) { - _cleanup_free_ UidRange *gid_range = NULL; + _cleanup_(uid_range_freep) UidRange *gid_range = NULL; int boundary_lines, gid_map_lines; - size_t n_gid_range = 0; - r = uid_range_load_userns(&gid_range, &n_gid_range, "/proc/self/gid_map"); + r = uid_range_load_userns(&gid_range, "/proc/self/gid_map"); if (r < 0) log_debug_errno(r, "Failed to load /proc/self/gid_map, ignoring: %m"); - boundary_lines = table_add_gid_boundaries(table, gid_range, n_gid_range); + boundary_lines = table_add_gid_boundaries(table, gid_range); if (boundary_lines < 0) return boundary_lines; - gid_map_lines = table_add_uid_map(table, gid_range, n_gid_range, add_unavailable_gid); + gid_map_lines = table_add_uid_map(table, gid_range, add_unavailable_gid); if (gid_map_lines < 0) return gid_map_lines; |