summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-03-13 11:21:49 +0100
committerLennart Poettering <lennart@poettering.net>2019-03-13 12:16:38 +0100
commit0cb8e3d1180330345088e68517700b950569386d (patch)
treef70e91030f741ec47b842fe5249df701558dc23c
parenttest: don't overwrite TESTDIR if already set (diff)
downloadsystemd-0cb8e3d1180330345088e68517700b950569386d.tar.xz
systemd-0cb8e3d1180330345088e68517700b950569386d.zip
util: split out namespace related stuff into a new namespace-util.[ch] pair
Just some minor reorganiztion.
Diffstat (limited to '')
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/namespace-util.c172
-rw-r--r--src/basic/namespace-util.h9
-rw-r--r--src/basic/process-util.c1
-rw-r--r--src/basic/process-util.h1
-rw-r--r--src/basic/stat-util.c46
-rw-r--r--src/basic/stat-util.h2
-rw-r--r--src/basic/terminal-util.c1
-rw-r--r--src/basic/util.c115
-rw-r--r--src/basic/util.h3
-rw-r--r--src/core/machine-id-setup.c1
-rw-r--r--src/core/namespace.c1
-rw-r--r--src/libsystemd/sd-bus/bus-container.c1
-rw-r--r--src/machine/machine-dbus.c1
-rw-r--r--src/nspawn/nspawn.c1
-rw-r--r--src/shared/logs-show.c1
-rw-r--r--src/test/test-stat-util.c1
17 files changed, 193 insertions, 166 deletions
diff --git a/src/basic/meson.build b/src/basic/meson.build
index c62e4a3b59..4cfd3c861d 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -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
index 0000000000..67bdaa19d5
--- /dev/null
+++ b/src/basic/namespace-util.c
@@ -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
index 0000000000..8c17ce91b2
--- /dev/null
+++ b/src/basic/namespace-util.h
@@ -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);
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 78ce43b944..615b6d4044 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -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"
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index c85ea30ecc..9950723996 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -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"
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index ea2bbc368b..2cd722c106 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -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;
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index 74fb7251b3..5aca17c04a 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -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
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 0f38120729..4702e91732 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -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"
diff --git a/src/basic/util.c b/src/basic/util.c
index e577c93e60..6f68bc404e 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -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;
diff --git a/src/basic/util.h b/src/basic/util.h
index dc33d66067..82851e910c 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -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);
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index aae548064e..9d3096e3ac 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -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"
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 4ee2b78653..3657e935ee 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -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"
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 2cfeefc2c3..40b0e8a947 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -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"
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 7a558df898..1ee878055e 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -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"
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 64a30a5b9a..c6cc82b12f 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -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"
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 15ef0f19ff..5fb736f633 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -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"
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 0e2155e911..e3d89d6e26 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -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"