From: Masatake YAMATO Date: Thu, 2 Oct 2025 16:21:21 +0000 (+0900) Subject: lsns: don't abort if /proc/self/ns/user is absent; probe other ns entries X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e4d54e9847035ca82816330d46be9088d727ff4;p=thirdparty%2Futil-linux.git lsns: don't abort if /proc/self/ns/user is absent; probe other ns entries 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 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 --- diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c index 074df806b..14556987c 100644 --- a/sys-utils/lsns.c +++ b/sys-utils/lsns.c @@ -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[])