From adcc8059292edc0b3bcb5b87a387e5d85cedee32 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 7 Jan 2025 10:53:01 +0100 Subject: [PATCH] namespace-util: return recognizable error if namespace_open_by_type() fails because ns type not supported This makes sure the the codepath that derives an nsfd from a pid works the same for the pidfd case and the non-pidfd case: if we can verify that /proc/ is mounted but the /proc/$PID/ns/ files are missing, we can assume the ns type is not supported by the kernel. Hence return the same ENOPKG error in this case as we already do in the pidfd ioctl based codepath. --- src/basic/namespace-util.c | 18 ++++++++++++------ src/test/test-namespace.c | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c index 9293999a01..88d122ea6c 100644 --- a/src/basic/namespace-util.c +++ b/src/basic/namespace-util.c @@ -71,13 +71,19 @@ static int pidref_namespace_open_by_type_internal(const PidRef *pidref, Namespac const char *p; p = pid_namespace_path(pidref->pid, type); - nsfd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC); - if (nsfd < 0) { - if (errno == ENOENT && proc_mounted() == 0) - return -ENOSYS; + nsfd = RET_NERRNO(open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC)); + if (nsfd == -ENOENT) { + r = proc_mounted(); + if (r == 0) + return -ENOSYS; /* /proc/ is not available or not set up properly, we're most likely + in some chroot environment. */ + if (r > 0) + return -ENOPKG; /* If /proc/ is definitely around then this means the namespace type is not supported */ - return -errno; + /* can't determine? then propagate original error */ } + if (nsfd < 0) + return nsfd; if (!need_verify) { /* Otherwise we verify on our own */ r = pidref_verify(pidref); @@ -143,7 +149,7 @@ int pidref_namespace_open( if (ret_userns_fd) { userns_fd = pidref_namespace_open_by_type_internal(pidref, NAMESPACE_USER, &need_verify); - if (userns_fd < 0 && !IN_SET(userns_fd, -ENOENT, -ENOPKG)) + if (userns_fd < 0 && userns_fd != -ENOPKG) return userns_fd; } diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c index d646306acf..6a0459e1fa 100644 --- a/src/test/test-namespace.c +++ b/src/test/test-namespace.c @@ -172,7 +172,7 @@ TEST(fd_is_namespace) { ASSERT_OK_ZERO(fd_is_namespace(STDERR_FILENO, NAMESPACE_NET)); fd = namespace_open_by_type(NAMESPACE_MOUNT); - if (IN_SET(fd, -ENOSYS, -ENOENT)) { + if (IN_SET(fd, -ENOSYS, -ENOPKG)) { log_notice("Path %s not found, skipping test", "/proc/self/ns/mnt"); return; }