summaryrefslogtreecommitdiff
path: root/src/nspawn
diff options
context:
space:
mode:
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-expose-ports.c4
-rw-r--r--src/nspawn/nspawn-mount.c59
-rw-r--r--src/nspawn/nspawn-mount.h3
-rw-r--r--src/nspawn/nspawn.c28
4 files changed, 71 insertions, 23 deletions
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index 9e63d88b69..3658f45381 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -194,7 +194,7 @@ int expose_port_send_rtnl(int send_fd) {
/* Store away the fd in the socket, so that it stays open as
* long as we run the child */
- r = send_one_fd(send_fd, fd);
+ r = send_one_fd(send_fd, fd, 0);
if (r < 0)
return log_error_errno(r, "Failed to send netlink fd: %m");
@@ -214,7 +214,7 @@ int expose_port_watch_rtnl(
assert(recv_fd >= 0);
assert(ret);
- fd = receive_one_fd(recv_fd);
+ fd = receive_one_fd(recv_fd, 0);
if (fd < 0)
return log_error_errno(fd, "Failed to recv netlink fd: %m");
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 2bca39f45d..3d302ef9ad 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -216,8 +216,55 @@ static int tmpfs_patch_options(
return !!buf;
}
+int mount_sysfs(const char *dest) {
+ const char *full, *top, *x;
+
+ top = prefix_roota(dest, "/sys");
+ full = prefix_roota(top, "/full");
+
+ (void) mkdir(full, 0755);
+
+ if (mount("sysfs", full, "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
+ return log_error_errno(errno, "Failed to mount sysfs to %s: %m", full);
+
+ FOREACH_STRING(x, "block", "bus", "class", "dev", "devices", "kernel") {
+ _cleanup_free_ char *from = NULL, *to = NULL;
+
+ from = prefix_root(full, x);
+ if (!from)
+ return log_oom();
+
+ to = prefix_root(top, x);
+ if (!to)
+ return log_oom();
+
+ (void) mkdir(to, 0755);
+
+ if (mount(from, to, NULL, MS_BIND, NULL) < 0)
+ return log_error_errno(errno, "Failed to mount /sys/%s into place: %m", x);
+
+ if (mount(NULL, to, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
+ return log_error_errno(errno, "Failed to mount /sys/%s read-only: %m", x);
+ }
+
+ if (umount(full) < 0)
+ return log_error_errno(errno, "Failed to unmount %s: %m", full);
+
+ if (rmdir(full) < 0)
+ return log_error_errno(errno, "Failed to remove %s: %m", full);
+
+ x = prefix_roota(top, "/fs/kdbus");
+ (void) mkdir(x, 0755);
+
+ if (mount(NULL, top, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
+ return log_error_errno(errno, "Failed to make %s read-only: %m", top);
+
+ return 0;
+}
+
int mount_all(const char *dest,
- bool userns, uid_t uid_shift, uid_t uid_range,
+ bool use_userns, bool in_userns,
+ uid_t uid_shift, uid_t uid_range,
const char *selinux_apifs_context) {
typedef struct MountPoint {
@@ -234,7 +281,7 @@ int mount_all(const char *dest,
{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true },
{ "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true }, /* Bind mount first */
{ NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true, true }, /* Then, make it r/o */
- { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false },
+ { "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false },
{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false },
{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false },
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false },
@@ -252,7 +299,7 @@ int mount_all(const char *dest,
_cleanup_free_ char *where = NULL, *options = NULL;
const char *o;
- if (userns != mount_table[k].userns)
+ if (in_userns != mount_table[k].userns)
continue;
where = prefix_root(dest, mount_table[k].where);
@@ -278,7 +325,7 @@ int mount_all(const char *dest,
o = mount_table[k].options;
if (streq_ptr(mount_table[k].type, "tmpfs")) {
- r = tmpfs_patch_options(o, userns, uid_shift, uid_range, selinux_apifs_context, &options);
+ r = tmpfs_patch_options(o, use_userns, uid_shift, uid_range, selinux_apifs_context, &options);
if (r < 0)
return log_oom();
if (r > 0)
@@ -534,7 +581,7 @@ static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controlle
char *to;
int r;
- to = strjoina(dest, "/sys/fs/cgroup/", hierarchy);
+ to = strjoina(strempty(dest), "/sys/fs/cgroup/", hierarchy);
r = path_is_mount_point(to, 0);
if (r < 0 && r != -ENOENT)
@@ -569,6 +616,8 @@ static int mount_legacy_cgroups(
cgroup_root = prefix_roota(dest, "/sys/fs/cgroup");
+ (void) mkdir_p(cgroup_root, 0755);
+
/* Mount a tmpfs to /sys/fs/cgroup if it's not mounted there yet. */
r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW);
if (r < 0)
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 5abd44cc4b..54cab87665 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -57,7 +57,8 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
int custom_mount_compare(const void *a, const void *b);
-int mount_all(const char *dest, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
+int mount_all(const char *dest, bool use_userns, bool in_userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
+int mount_sysfs(const char *dest);
int mount_cgroups(const char *dest, bool unified_requested, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
int mount_systemd_cgroup_writable(const char *dest, bool unified_requested);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 7451c2bf64..f4a2e3d9ba 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -50,7 +50,6 @@
#include "base-filesystem.h"
#include "blkid-util.h"
#include "btrfs-util.h"
-#include "build.h"
#include "cap-list.h"
#include "capability.h"
#include "cgroup-util.h"
@@ -84,12 +83,12 @@
#include "udev-util.h"
#include "util.h"
-#include "nspawn-settings.h"
+#include "nspawn-cgroup.h"
+#include "nspawn-expose-ports.h"
#include "nspawn-mount.h"
#include "nspawn-network.h"
-#include "nspawn-expose-ports.h"
-#include "nspawn-cgroup.h"
#include "nspawn-register.h"
+#include "nspawn-settings.h"
#include "nspawn-setuid.h"
typedef enum ContainerStatus {
@@ -414,9 +413,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'D':
r = set_sanitized_path(&arg_directory, optarg);
@@ -1291,7 +1288,7 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
/* Store away the fd in the socket, so that it stays open as
* long as we run the child */
- r = send_one_fd(kmsg_socket, fd);
+ r = send_one_fd(kmsg_socket, fd, 0);
safe_close(fd);
if (r < 0)
@@ -2282,8 +2279,6 @@ static int wait_for_container(pid_t pid, ContainerStatus *container) {
return r;
}
-static void nop_handler(int sig) {}
-
static int on_orderly_shutdown(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
pid_t pid;
@@ -2455,7 +2450,11 @@ static int inner_child(
}
}
- r = mount_all(NULL, true, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_all(NULL, arg_userns, true, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ if (r < 0)
+ return r;
+
+ r = mount_sysfs(NULL);
if (r < 0)
return r;
@@ -2706,7 +2705,7 @@ static int outer_child(
return log_error_errno(r, "Failed to make tree read-only: %m");
}
- r = mount_all(directory, false, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
+ r = mount_all(directory, arg_userns, false, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
if (r < 0)
return r;
@@ -3241,7 +3240,7 @@ int main(int argc, char *argv[]) {
ContainerStatus container_status;
_cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
static const struct sigaction sa = {
- .sa_handler = nop_handler,
+ .sa_handler = nop_signal_handler,
.sa_flags = SA_NOCLDSTOP,
};
int ifi = 0;
@@ -3338,8 +3337,7 @@ int main(int argc, char *argv[]) {
barrier_set_role(&barrier, BARRIER_PARENT);
- fdset_free(fds);
- fds = NULL;
+ fds = fdset_free(fds);
kmsg_socket_pair[1] = safe_close(kmsg_socket_pair[1]);
rtnl_socket_pair[1] = safe_close(rtnl_socket_pair[1]);