]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace-util: return recognizable error if namespace_open_by_type() fails because...
authorLennart Poettering <lennart@poettering.net>
Tue, 7 Jan 2025 09:53:01 +0000 (10:53 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Jan 2025 22:51:28 +0000 (23:51 +0100)
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
src/test/test-namespace.c

index 9293999a019fed1fa7c56a78ac567acf9f839ba8..88d122ea6c594e32be4e1900b09d2647c102ebd2 100644 (file)
@@ -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;
         }
 
index d646306acfb19555b6607543b4be00198764bab1..6a0459e1faea83e436720b51a5483bdca9aeeb07 100644 (file)
@@ -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;
         }