]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsns: don't abort if /proc/self/ns/user is absent; probe other ns entries
authorMasatake YAMATO <yamato@redhat.com>
Thu, 2 Oct 2025 16:21:21 +0000 (01:21 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Thu, 2 Oct 2025 17:10:33 +0000 (02:10 +0900)
In 7d5036fdafe0 ("lsns: show namespaces only kept alive by open file
descriptors"), I added code that calls stat(2) on /proc/self/ns/user
and made lsns exit after reporting an error if the call failed. I
assumed /proc/self/ns/user would be available on all platforms.

As Axel Karjalainen reported (link below), that assumption was
wrong: on some platforms, the file is absent. Exiting for this reason
is undesirable.

The stat(2) call is used to obtain the dev_t of the backing device of
nsfs. However, /proc/self/ns/user is not the only source; calling
stat(2) on other namespace files under /proc/self/ns yields the same
dev_t. This change iterates over entries under /proc/self/ns and uses
the first one whose stat(2) succeeds.

Reported-by: Axel Karjalainen <axel@axka.fi>
Link: https://github.com/util-linux/util-linux/pull/2902#issuecomment-3348630885
Fixes: 7d5036fdafe0 ("lsns: show namespaces only kept alive by open file descriptors")
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
sys-utils/lsns.c

index 074df806bf7a0555db68b3ac7aac49580091c18f..14556987c7456bcb9b1148a311671d72e3da119b 100644 (file)
@@ -1605,14 +1605,28 @@ static void __attribute__((__noreturn__)) list_colunms(struct lsns *ls)
    exit(EXIT_SUCCESS);
 }
 
+static int stat_self_ns (const char *ns, struct stat *st)
+{
+       int r;
+       char *fname = NULL;
+
+       xasprintf(&fname, "/proc/self/ns/%s", ns);
+       r = stat(fname, st);
+       free(fname);
+
+       return r;
+}
+
 static dev_t read_nsfs_dev(void)
 {
        struct stat st;
 
-       if (stat("/proc/self/ns/user", &st) < 0)
-               err(EXIT_FAILURE, _("failed to do stat /proc/self/ns/user"));
+       for (size_t i = 0; i < ARRAY_SIZE(ns_names); i++) {
+               if (stat_self_ns(ns_names[i], &st) == 0)
+                       return st.st_dev;
+       }
 
-       return st.st_dev;
+       return -1;
 }
 
 int main(int argc, char *argv[])