]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
unshare: Fix --map-auto regression
authorChris Webb <chris@arachsys.com>
Mon, 29 Jun 2026 15:37:27 +0000 (15:37 +0000)
committerChris Webb <chris@arachsys.com>
Mon, 29 Jun 2026 15:37:27 +0000 (15:37 +0000)
Commit 07935158 fixed an unshare --user bug which wasted a UID/GID when
--map-auto was used with --map-root-user. This bug meant that, for example,
a user with a single extra UID and GID delegated to them in /etc/subuid
and /etc/subgid would not get that user or group mapped at all if they
attempted unshare -r --map-auto.

Two years later, commit b64b769b added unshare --map-subids to identity-map
subuids and subgids into a user namespace, but incorrectly removed a
load-bearing 'else if' in passing, and reintroduced the original bug.

Ironically, map->inner != -1 for an identity mapping, so the 'if' vs
'else if' change has no effect on the --map-subids option; it only breaks
--map-auto.

Fix the unshare -r --map-auto behaviour again.

Signed-off-by: Chris Webb <chris@arachsys.com>
sys-utils/unshare.c

index f25e9e5c2754f978d59bc8a4410d6f15dc9e089c..1e96ba478c39ccac6621e1bd03ba12fc299792fc 100644 (file)
@@ -535,15 +535,14 @@ static void add_single_map_range(struct map_range **chain, unsigned int outer,
                                 *next = map->next;
                unsigned int inner_offset, outer_offset;
 
-               /* Start inner IDs from zero for an auto mapping */
-               if (map->inner + 1 == 0)
-                       map->inner = 0;
-
                /*
-                * If the single mapping exists and overlaps the range, remove
-                * an ID
+                * Start inner IDs from zero for an auto mapping; otherwise,
+                * if the single mapping exists and overlaps the range,
+                * remove an ID
                 */
-               if (inner + 1 != 0 &&
+               if (map->inner + 1 == 0)
+                       map->inner = 0;
+               else if (inner + 1 != 0 &&
                    ((outer >= map->outer && outer <= map->outer + map->count) ||
                     (inner >= map->inner && inner <= map->inner + map->count)))
                        map->count--;