summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-03-31 14:28:32 +0200
committerLennart Poettering <lennart@poettering.net>2022-04-01 11:20:12 +0200
commit556560495ef695d7495e3bb930e8ce9f3964b99e (patch)
tree56e54df9e4d67f10b0f7d40dc66e38fbea88b763
parentuid-range: add some overflow checks (diff)
downloadsystemd-556560495ef695d7495e3bb930e8ce9f3964b99e.tar.xz
systemd-556560495ef695d7495e3bb930e8ce9f3964b99e.zip
uid-range: replace uid_range_contains() by more generalized uid_range_covers()
The former checks if one UID is inside the uid range set. The latter checks if a full UID range is inside the uid range set. The former is hence a special case of the latter.
-rw-r--r--src/shared/uid-range.c13
-rw-r--r--src/shared/uid-range.h6
-rw-r--r--src/test/test-uid-range.c17
3 files changed, 31 insertions, 5 deletions
diff --git a/src/shared/uid-range.c b/src/shared/uid-range.c
index 1fa7218ee6..1b4396a34c 100644
--- a/src/shared/uid-range.c
+++ b/src/shared/uid-range.c
@@ -179,12 +179,17 @@ int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid) {
return 1;
}
-bool uid_range_contains(const UidRange *p, size_t n, uid_t uid) {
- assert(p);
- assert(uid);
+bool uid_range_covers(const UidRange *p, size_t n, uid_t start, uid_t nr) {
+ assert(p || n == 0);
+
+ 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 (uid >= p[i].start && uid < p[i].start + p[i].nr)
+ if (start >= p[i].start && start + nr <= p[i].start + p[i].nr)
return true;
return false;
diff --git a/src/shared/uid-range.h b/src/shared/uid-range.h
index d256a6eebb..7259c9e371 100644
--- a/src/shared/uid-range.h
+++ b/src/shared/uid-range.h
@@ -12,6 +12,10 @@ int uid_range_add(UidRange **p, size_t *n, uid_t start, uid_t nr);
int uid_range_add_str(UidRange **p, size_t *n, const char *s);
int uid_range_next_lower(const UidRange *p, size_t n, uid_t *uid);
-bool uid_range_contains(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);
+
+static inline bool uid_range_contains(const UidRange *p, size_t n, uid_t uid) {
+ return uid_range_covers(p, n, uid, 1);
+}
int uid_range_load_userns(UidRange **p, size_t *n, const char *path);
diff --git a/src/test/test-uid-range.c b/src/test/test-uid-range.c
index 2e39628cef..be8530bdd8 100644
--- a/src/test/test-uid-range.c
+++ b/src/test/test-uid-range.c
@@ -19,6 +19,10 @@ TEST(uid_range) {
size_t n = 0;
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);
@@ -29,6 +33,17 @@ TEST(uid_range) {
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));
+
search = UID_INVALID;
assert_se(uid_range_next_lower(p, n, &search));
assert_se(search == 999);
@@ -97,6 +112,8 @@ TEST(load_userns) {
assert_se(n == 1);
assert_se(p[0].start == 0);
assert_se(p[0].nr == UINT32_MAX);
+
+ assert_se(uid_range_covers(p, n, 0, UINT32_MAX));
}
assert_se(fopen_temporary(NULL, &f, &fn) >= 0);