summaryrefslogtreecommitdiff
path: root/src/nspawn
diff options
context:
space:
mode:
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-mount.c55
-rw-r--r--src/nspawn/nspawn-seccomp.c18
-rw-r--r--src/nspawn/nspawn.c8
3 files changed, 61 insertions, 20 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index 44dc9bfcf4..115de64cf9 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -300,6 +300,59 @@ int mount_sysfs(const char *dest) {
MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL);
}
+static int mkdir_userns(const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+ int r;
+
+ assert(path);
+
+ r = mkdir(path, mode);
+ if (r < 0 && errno != EEXIST)
+ return -errno;
+
+ if (!in_userns) {
+ r = lchown(path, uid_shift, uid_shift);
+ if (r < 0)
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int mkdir_userns_p(const char *prefix, const char *path, mode_t mode, bool in_userns, uid_t uid_shift) {
+ const char *p, *e;
+ int r;
+
+ assert(path);
+
+ if (prefix && !path_startswith(path, prefix))
+ return -ENOTDIR;
+
+ /* create every parent directory in the path, except the last component */
+ p = path + strspn(path, "/");
+ for (;;) {
+ char t[strlen(path) + 1];
+
+ e = p + strcspn(p, "/");
+ p = e + strspn(e, "/");
+
+ /* Is this the last component? If so, then we're done */
+ if (*p == 0)
+ break;
+
+ memcpy(t, path, e - path);
+ t[e-path] = 0;
+
+ if (prefix && path_startswith(prefix, t))
+ continue;
+
+ r = mkdir_userns(t, mode, in_userns, uid_shift);
+ if (r < 0)
+ return r;
+ }
+
+ return mkdir_userns(path, mode, in_userns, uid_shift);
+}
+
int mount_all(const char *dest,
bool use_userns, bool in_userns,
bool use_netns,
@@ -361,7 +414,7 @@ int mount_all(const char *dest,
if (mount_table[k].what && r > 0)
continue;
- r = mkdir_p(where, 0755);
+ r = mkdir_userns_p(dest, where, 0755, in_userns, uid_shift);
if (r < 0 && r != -EEXIST) {
if (mount_table[k].fatal)
return log_error_errno(r, "Failed to create directory %s: %m", where);
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index 44a0b397ab..03a397d30c 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -135,15 +135,9 @@ int setup_seccomp(uint64_t cap_list_retain) {
return 0;
}
- seccomp = seccomp_init(SCMP_ACT_ALLOW);
- if (!seccomp)
- return log_oom();
-
- r = seccomp_add_secondary_archs(seccomp);
- if (r < 0) {
- log_error_errno(r, "Failed to add secondary archs to seccomp filter: %m");
- goto finish;
- }
+ r = seccomp_init_conservative(&seccomp, SCMP_ACT_ALLOW);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate seccomp object: %m");
r = seccomp_add_default_syscall_filter(seccomp, cap_list_retain);
if (r < 0)
@@ -171,12 +165,6 @@ int setup_seccomp(uint64_t cap_list_retain) {
goto finish;
}
- r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
- if (r < 0) {
- log_error_errno(r, "Failed to unset NO_NEW_PRIVS: %m");
- goto finish;
- }
-
r = seccomp_load(seccomp);
if (r < 0) {
log_error_errno(r, "Failed to install seccomp audit filter: %m");
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 2cbe563953..295293858e 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2684,6 +2684,10 @@ static int inner_child(
}
}
+ r = reset_uid_gid();
+ if (r < 0)
+ return log_error_errno(r, "Couldn't become new root: %m");
+
r = mount_all(NULL,
arg_userns_mode != USER_NAMESPACE_NO,
true,
@@ -2726,10 +2730,6 @@ static int inner_child(
return r;
}
- r = reset_uid_gid();
- if (r < 0)
- return log_error_errno(r, "Couldn't become new root: %m");
-
r = setup_boot_id(NULL);
if (r < 0)
return r;