]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util: split out namespace related stuff into a new namespace-util.[ch] pair
authorLennart Poettering <lennart@poettering.net>
Wed, 13 Mar 2019 10:21:49 +0000 (11:21 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Mar 2019 11:16:38 +0000 (12:16 +0100)
Just some minor reorganiztion.

17 files changed:
src/basic/meson.build
src/basic/namespace-util.c [new file with mode: 0644]
src/basic/namespace-util.h [new file with mode: 0644]
src/basic/process-util.c
src/basic/process-util.h
src/basic/stat-util.c
src/basic/stat-util.h
src/basic/terminal-util.c
src/basic/util.c
src/basic/util.h
src/core/machine-id-setup.c
src/core/namespace.c
src/libsystemd/sd-bus/bus-container.c
src/machine/machine-dbus.c
src/nspawn/nspawn.c
src/shared/logs-show.c
src/test/test-stat-util.c

index c62e4a3b593101af976064d7188b642ffcc096ce..4cfd3c861decba6f38f2a7f2add6b6e2875978cf 100644 (file)
@@ -127,6 +127,8 @@ basic_sources = files('''
         mkdir.h
         mountpoint-util.c
         mountpoint-util.h
+        namespace-util.c
+        namespace-util.h
         nss-util.h
         ordered-set.c
         ordered-set.h
diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c
new file mode 100644 (file)
index 0000000..67bdaa1
--- /dev/null
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <fcntl.h>
+#include <linux/magic.h>
+
+#include "fd-util.h"
+#include "missing.h"
+#include "namespace-util.h"
+#include "process-util.h"
+#include "stat-util.h"
+#include "user-util.h"
+
+int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
+        _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
+        int rfd = -1;
+
+        assert(pid >= 0);
+
+        if (mntns_fd) {
+                const char *mntns;
+
+                mntns = procfs_file_alloca(pid, "ns/mnt");
+                mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (mntnsfd < 0)
+                        return -errno;
+        }
+
+        if (pidns_fd) {
+                const char *pidns;
+
+                pidns = procfs_file_alloca(pid, "ns/pid");
+                pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (pidnsfd < 0)
+                        return -errno;
+        }
+
+        if (netns_fd) {
+                const char *netns;
+
+                netns = procfs_file_alloca(pid, "ns/net");
+                netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (netnsfd < 0)
+                        return -errno;
+        }
+
+        if (userns_fd) {
+                const char *userns;
+
+                userns = procfs_file_alloca(pid, "ns/user");
+                usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
+                if (usernsfd < 0 && errno != ENOENT)
+                        return -errno;
+        }
+
+        if (root_fd) {
+                const char *root;
+
+                root = procfs_file_alloca(pid, "root");
+                rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+                if (rfd < 0)
+                        return -errno;
+        }
+
+        if (pidns_fd)
+                *pidns_fd = pidnsfd;
+
+        if (mntns_fd)
+                *mntns_fd = mntnsfd;
+
+        if (netns_fd)
+                *netns_fd = netnsfd;
+
+        if (userns_fd)
+                *userns_fd = usernsfd;
+
+        if (root_fd)
+                *root_fd = rfd;
+
+        pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
+
+        return 0;
+}
+
+int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
+        if (userns_fd >= 0) {
+                /* Can't setns to your own userns, since then you could
+                 * escalate from non-root to root in your own namespace, so
+                 * check if namespaces equal before attempting to enter. */
+                _cleanup_free_ char *userns_fd_path = NULL;
+                int r;
+                if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
+                        return -ENOMEM;
+
+                r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
+                if (r < 0)
+                        return r;
+                if (r)
+                        userns_fd = -1;
+        }
+
+        if (pidns_fd >= 0)
+                if (setns(pidns_fd, CLONE_NEWPID) < 0)
+                        return -errno;
+
+        if (mntns_fd >= 0)
+                if (setns(mntns_fd, CLONE_NEWNS) < 0)
+                        return -errno;
+
+        if (netns_fd >= 0)
+                if (setns(netns_fd, CLONE_NEWNET) < 0)
+                        return -errno;
+
+        if (userns_fd >= 0)
+                if (setns(userns_fd, CLONE_NEWUSER) < 0)
+                        return -errno;
+
+        if (root_fd >= 0) {
+                if (fchdir(root_fd) < 0)
+                        return -errno;
+
+                if (chroot(".") < 0)
+                        return -errno;
+        }
+
+        return reset_uid_gid();
+}
+
+int fd_is_network_ns(int fd) {
+        struct statfs s;
+        int r;
+
+        /* Checks whether the specified file descriptor refers to a network namespace. On old kernels there's no nice
+         * way to detect that, hence on those we'll return a recognizable error (EUCLEAN), so that callers can handle
+         * this somewhat nicely.
+         *
+         * This function returns > 0 if the fd definitely refers to a network namespace, 0 if it definitely does not
+         * refer to a network namespace, -EUCLEAN if we can't determine, and other negative error codes on error. */
+
+        if (fstatfs(fd, &s) < 0)
+                return -errno;
+
+        if (!is_fs_type(&s, NSFS_MAGIC)) {
+                /* On really old kernels, there was no "nsfs", and network namespace sockets belonged to procfs
+                 * instead. Handle that in a somewhat smart way. */
+
+                if (is_fs_type(&s, PROC_SUPER_MAGIC)) {
+                        struct statfs t;
+
+                        /* OK, so it is procfs. Let's see if our own network namespace is procfs, too. If so, then the
+                         * passed fd might refer to a network namespace, but we can't know for sure. In that case,
+                         * return a recognizable error. */
+
+                        if (statfs("/proc/self/ns/net", &t) < 0)
+                                return -errno;
+
+                        if (s.f_type == t.f_type)
+                                return -EUCLEAN; /* It's possible, we simply don't know */
+                }
+
+                return 0; /* No! */
+        }
+
+        r = ioctl(fd, NS_GET_NSTYPE);
+        if (r < 0) {
+                if (errno == ENOTTY) /* Old kernels didn't know this ioctl, let's also return a recognizable error in that case */
+                        return -EUCLEAN;
+
+                return -errno;
+        }
+
+        return r == CLONE_NEWNET;
+}
diff --git a/src/basic/namespace-util.h b/src/basic/namespace-util.h
new file mode 100644 (file)
index 0000000..8c17ce9
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <sys/types.h>
+
+int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
+int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
+
+int fd_is_network_ns(int fd);
index 78ce43b944c126be095680446e9aeaa88583a708..615b6d4044a53b8fb800abb56320bf26b0bfc1cd 100644 (file)
@@ -33,6 +33,7 @@
 #include "log.h"
 #include "macro.h"
 #include "missing.h"
+#include "namespace-util.h"
 #include "process-util.h"
 #include "raw-clone.h"
 #include "rlimit-util.h"
index c85ea30ecc78544719b22ec625c3ca7e9d61b20a..9950723996fe22a3d8198be98c53a9f3b34714d5 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/resource.h>
 #include <sys/types.h>
 
+#include "alloc-util.h"
 #include "format-util.h"
 #include "ioprio.h"
 #include "macro.h"
index ea2bbc368b1367a45039cfea2c5349772edae139..2cd722c1064be5ba4fd76525100c90a125ca574e 100644 (file)
@@ -223,52 +223,6 @@ int fd_is_network_fs(int fd) {
         return is_network_fs(&s);
 }
 
-int fd_is_network_ns(int fd) {
-        struct statfs s;
-        int r;
-
-        /* Checks whether the specified file descriptor refers to a network namespace. On old kernels there's no nice
-         * way to detect that, hence on those we'll return a recognizable error (EUCLEAN), so that callers can handle
-         * this somewhat nicely.
-         *
-         * This function returns > 0 if the fd definitely refers to a network namespace, 0 if it definitely does not
-         * refer to a network namespace, -EUCLEAN if we can't determine, and other negative error codes on error. */
-
-        if (fstatfs(fd, &s) < 0)
-                return -errno;
-
-        if (!is_fs_type(&s, NSFS_MAGIC)) {
-                /* On really old kernels, there was no "nsfs", and network namespace sockets belonged to procfs
-                 * instead. Handle that in a somewhat smart way. */
-
-                if (is_fs_type(&s, PROC_SUPER_MAGIC)) {
-                        struct statfs t;
-
-                        /* OK, so it is procfs. Let's see if our own network namespace is procfs, too. If so, then the
-                         * passed fd might refer to a network namespace, but we can't know for sure. In that case,
-                         * return a recognizable error. */
-
-                        if (statfs("/proc/self/ns/net", &t) < 0)
-                                return -errno;
-
-                        if (s.f_type == t.f_type)
-                                return -EUCLEAN; /* It's possible, we simply don't know */
-                }
-
-                return 0; /* No! */
-        }
-
-        r = ioctl(fd, NS_GET_NSTYPE);
-        if (r < 0) {
-                if (errno == ENOTTY) /* Old kernels didn't know this ioctl, let's also return a recognizable error in that case */
-                        return -EUCLEAN;
-
-                return -errno;
-        }
-
-        return r == CLONE_NEWNET;
-}
-
 int path_is_temporary_fs(const char *path) {
         _cleanup_close_ int fd = -1;
 
index 74fb7251b3872c4f08f38383bab7ab4c0f8979cd..5aca17c04a33067e04ee12aaf54009a3b9050d6e 100644 (file)
@@ -50,8 +50,6 @@ bool is_network_fs(const struct statfs *s) _pure_;
 int fd_is_temporary_fs(int fd);
 int fd_is_network_fs(int fd);
 
-int fd_is_network_ns(int fd);
-
 int path_is_temporary_fs(const char *path);
 
 /* Because statfs.t_type can be int on some architectures, we have to cast
index 0f3812072938f556c6c9c7c7512fcf97d860a844..4702e917324a80fc26b1c3beeffdd82855e4e7ce 100644 (file)
@@ -32,6 +32,7 @@
 #include "io-util.h"
 #include "log.h"
 #include "macro.h"
+#include "namespace-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "proc-cmdline.h"
index e577c93e60d61b058d09aae6ffb4c87680082d19..6f68bc404e31d44d8943109cdb15f919530f4896 100644 (file)
@@ -294,121 +294,6 @@ int container_get_leader(const char *machine, pid_t *pid) {
         return 0;
 }
 
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
-        _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
-        int rfd = -1;
-
-        assert(pid >= 0);
-
-        if (mntns_fd) {
-                const char *mntns;
-
-                mntns = procfs_file_alloca(pid, "ns/mnt");
-                mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (mntnsfd < 0)
-                        return -errno;
-        }
-
-        if (pidns_fd) {
-                const char *pidns;
-
-                pidns = procfs_file_alloca(pid, "ns/pid");
-                pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (pidnsfd < 0)
-                        return -errno;
-        }
-
-        if (netns_fd) {
-                const char *netns;
-
-                netns = procfs_file_alloca(pid, "ns/net");
-                netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (netnsfd < 0)
-                        return -errno;
-        }
-
-        if (userns_fd) {
-                const char *userns;
-
-                userns = procfs_file_alloca(pid, "ns/user");
-                usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-                if (usernsfd < 0 && errno != ENOENT)
-                        return -errno;
-        }
-
-        if (root_fd) {
-                const char *root;
-
-                root = procfs_file_alloca(pid, "root");
-                rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
-                if (rfd < 0)
-                        return -errno;
-        }
-
-        if (pidns_fd)
-                *pidns_fd = pidnsfd;
-
-        if (mntns_fd)
-                *mntns_fd = mntnsfd;
-
-        if (netns_fd)
-                *netns_fd = netnsfd;
-
-        if (userns_fd)
-                *userns_fd = usernsfd;
-
-        if (root_fd)
-                *root_fd = rfd;
-
-        pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
-
-        return 0;
-}
-
-int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
-        if (userns_fd >= 0) {
-                /* Can't setns to your own userns, since then you could
-                 * escalate from non-root to root in your own namespace, so
-                 * check if namespaces equal before attempting to enter. */
-                _cleanup_free_ char *userns_fd_path = NULL;
-                int r;
-                if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
-                        return -ENOMEM;
-
-                r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
-                if (r < 0)
-                        return r;
-                if (r)
-                        userns_fd = -1;
-        }
-
-        if (pidns_fd >= 0)
-                if (setns(pidns_fd, CLONE_NEWPID) < 0)
-                        return -errno;
-
-        if (mntns_fd >= 0)
-                if (setns(mntns_fd, CLONE_NEWNS) < 0)
-                        return -errno;
-
-        if (netns_fd >= 0)
-                if (setns(netns_fd, CLONE_NEWNET) < 0)
-                        return -errno;
-
-        if (userns_fd >= 0)
-                if (setns(userns_fd, CLONE_NEWUSER) < 0)
-                        return -errno;
-
-        if (root_fd >= 0) {
-                if (fchdir(root_fd) < 0)
-                        return -errno;
-
-                if (chroot(".") < 0)
-                        return -errno;
-        }
-
-        return reset_uid_gid();
-}
-
 uint64_t physical_memory(void) {
         _cleanup_free_ char *root = NULL, *value = NULL;
         uint64_t mem, lim;
index dc33d660674aeb51fea51b27005dac91cf653a40..82851e910cabe632250f24a1fb677a510fb04154 100644 (file)
@@ -237,9 +237,6 @@ static inline unsigned log2u_round_up(unsigned x) {
 
 int container_get_leader(const char *machine, pid_t *pid);
 
-int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
-int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
-
 uint64_t physical_memory(void);
 uint64_t physical_memory_scale(uint64_t v, uint64_t max);
 
index aae548064e5035fb7c9f9d2898d68e3528073903..9d3096e3ac98391bbf3208f3819dbea825175785 100644 (file)
@@ -16,6 +16,7 @@
 #include "macro.h"
 #include "mkdir.h"
 #include "mountpoint-util.h"
+#include "namespace-util.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "stat-util.h"
index 4ee2b786538d0a1043de52d26317dba1da217c88..3657e935eeb211e3dd4555155fdc4acadf4564b1 100644 (file)
@@ -21,6 +21,7 @@
 #include "mkdir.h"
 #include "mount-util.h"
 #include "mountpoint-util.h"
+#include "namespace-util.h"
 #include "namespace.h"
 #include "path-util.h"
 #include "selinux-util.h"
index 2cfeefc2c3f8ae324da0b9241e96746433bfc5fb..40b0e8a94713e2dcb8427b914cb614be733c605e 100644 (file)
@@ -7,6 +7,7 @@
 #include "bus-internal.h"
 #include "bus-socket.h"
 #include "fd-util.h"
+#include "namespace-util.h"
 #include "process-util.h"
 #include "util.h"
 
index 7a558df8983c0267f73bf6017536e86d0e38394a..1ee878055eb164ccafe2f640ee26c004bc2fe586 100644 (file)
@@ -29,6 +29,7 @@
 #include "machine.h"
 #include "missing_capability.h"
 #include "mkdir.h"
+#include "namespace-util.h"
 #include "os-util.h"
 #include "path-util.h"
 #include "process-util.h"
index 64a30a5b9a800bce23932b4488fcae1b949fc998..c6cc82b12f4580314102ae99aecb4ec25f418a67 100644 (file)
@@ -61,6 +61,7 @@
 #include "mkdir.h"
 #include "mount-util.h"
 #include "mountpoint-util.h"
+#include "namespace-util.h"
 #include "netlink-util.h"
 #include "nspawn-cgroup.h"
 #include "nspawn-def.h"
index 15ef0f19ff8f5ced3416c41a345906f8aef8a381..5fb736f63307ab4e2e02973a2d8d8118ed7188b5 100644 (file)
@@ -25,6 +25,7 @@
 #include "log.h"
 #include "logs-show.h"
 #include "macro.h"
+#include "namespace-util.h"
 #include "output-mode.h"
 #include "parse-util.h"
 #include "process-util.h"
index 0e2155e91134cc3ca4871b462a357ba83152dfeb..e3d89d6e269132805378589768c83a5fdb6f6168 100644 (file)
@@ -9,6 +9,7 @@
 #include "macro.h"
 #include "missing.h"
 #include "mountpoint-util.h"
+#include "namespace-util.h"
 #include "path-util.h"
 #include "stat-util.h"
 #include "tmpfile-util.h"