]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
find_range: avoid count==0 bug
authorSerge Hallyn <serge@hallyn.com>
Sun, 19 Jul 2026 13:30:11 +0000 (08:30 -0500)
committerSerge Hallyn <serge@hallyn.com>
Sun, 19 Jul 2026 14:36:39 +0000 (09:36 -0500)
If someone has a subuid range with count==0, the variable last is
calculated as first + count - 1, meaning last == first - 1.  Since
the calculated range wraps around, this can invalidate later checks.

Check for this case explicitly.

Because of other checks, this can only lead to erroneous ranges
being created if the first loweruid is 0.  This means that the
subid range has to be user:0:0, which is doubly wrong, and should
never be seen in the real world.

A note on formatting: the calculations of first and last are done in
their declarations.  If range->count == 0, these go unused.  The
alternatives would be to declare the variables later in the scope -
which we do not do - or to assign them later, adding 3 more lines in
each scope.

Since this case (again) should never happen, it's not worth avoiding
the extra assignments in this error case.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
Reported-by: Mohammad Hossein Abedini <mhmd.abedinii@gmail.com>
lib/subordinateio.c

index 97994168a3d7fd623f5d37c463634c58610bfcbd..8542d793272e9a28c344c325df17d7f1665d7a90 100644 (file)
@@ -222,6 +222,9 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
                unsigned long first = range->start;
                unsigned long last = first + range->count - 1;
 
+               if (range->count == 0)
+                       continue;
+
                if (!streq(range->owner, owner))
                        continue;
 
@@ -249,6 +252,9 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
                unsigned long first = range->start;
                unsigned long last = first + range->count - 1;
 
+               if (range->count == 0)
+                       continue;
+
                /* For performance reasons check range before using getpwnam() */
                if ((val < first) || (val > last)) {
                        continue;