mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 17:51:22 +03:00
nspawn: really lchown(uid/gid)
https://github.com/systemd/systemd/pull/4372#issuecomment-253723849: * `mount_all (outer_child)` creates `container_dir/sys/fs/selinux` * `mount_all (outer_child)` doesn't patch `container_dir/sys/fs` and so on. * `mount_sysfs (inner_child)` tries to create `/sys/fs/cgroup` * This fails 370 stat("/sys/fs", {st_dev=makedev(0, 28), st_ino=13880, st_mode=S_IFDIR|0755, st_nlink=3, st_uid=65534, st_gid=65534, st_blksize=4096, st_blocks=0, st_size=60, st_atime=2016/10/14-05:16:43.398665943, st_mtime=2016/10/14-05:16:43.399665943, st_ctime=2016/10/14-05:16:43.399665943}) = 0 370 mkdir("/sys/fs/cgroup", 0755) = -1 EACCES (Permission denied) * `mount_syfs (inner_child)` ignores that error and mount(NULL, "/sys", NULL, MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_REMOUNT|MS_BIND, NULL) = 0 * `mount_cgroups` finally fails
This commit is contained in:
parent
548bd57376
commit
63eae72312
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user