diff options
author | Adrian Szyndela <adrian.s@samsung.com> | 2020-03-26 16:03:37 +0100 |
---|---|---|
committer | Adrian Szyndela <adrian.s@samsung.com> | 2020-03-26 16:03:37 +0100 |
commit | 0dbfabccd0e6d8fecc58a19bb5b4db2842e88364 (patch) | |
tree | aaac28e9f4d8588f149f12f8a2f70e866e26ed6c /src/nspawn | |
parent | 6926d6fb85cdf9148d949c6e29fad3651c2efb4b (diff) | |
parent | 738ab7502afb7663d9aacdd73e79025aa7cd0a9b (diff) | |
download | systemd-0dbfabccd0e6d8fecc58a19bb5b4db2842e88364.tar.gz systemd-0dbfabccd0e6d8fecc58a19bb5b4db2842e88364.tar.bz2 systemd-0dbfabccd0e6d8fecc58a19bb5b4db2842e88364.zip |
Merge v238 into tizen
systemd 238
Diffstat (limited to 'src/nspawn')
-rw-r--r-- | src/nspawn/nspawn-mount.c | 59 | ||||
-rw-r--r-- | src/nspawn/nspawn-setuid.c | 78 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 28 |
3 files changed, 48 insertions, 117 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 68b4f64909..7fb41c126f 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -48,7 +48,7 @@ CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t) { assert(t >= 0); assert(t < _CUSTOM_MOUNT_TYPE_MAX); - c = realloc_multiply(*l, (*n + 1), sizeof(CustomMount)); + c = reallocarray(*l, *n + 1, sizeof(CustomMount)); if (!c) return NULL; @@ -548,21 +548,21 @@ int mount_all(const char *dest, { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */ { "/proc/sys/net", "/proc/sys/net", NULL, NULL, MS_BIND, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS }, /* (except for this) */ { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */ - { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL, NULL, MS_BIND, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */ - { NULL, "/proc/sysrq-trigger", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */ + { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL, NULL, MS_BIND, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */ + { NULL, "/proc/sysrq-trigger", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */ /* outer child mounts */ - { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL }, + { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL }, { "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS }, { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO }, /* skipped if above was mounted */ - { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL }, /* skipped if above was mounted */ + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL }, /* skipped if above was mounted */ { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, MOUNT_FATAL }, { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL }, { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL }, #if HAVE_SELINUX - { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, 0 }, /* Bind mount first */ - { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, 0 }, /* Then, make it r/o */ + { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, 0 }, /* Bind mount first */ + { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, 0 }, /* Then, make it r/o */ #endif }; @@ -637,56 +637,15 @@ int mount_all(const char *dest, return 0; } -static int parse_mount_bind_options(const char *options, unsigned long *mount_flags, char **mount_opts) { - const char *p = options; - unsigned long flags = *mount_flags; - char *opts = NULL; - int r; - - assert(options); - - for (;;) { - _cleanup_free_ char *word = NULL; - - r = extract_first_word(&p, &word, ",", 0); - if (r < 0) - return log_error_errno(r, "Failed to extract mount option: %m"); - if (r == 0) - break; - - if (streq(word, "rbind")) - flags |= MS_REC; - else if (streq(word, "norbind")) - flags &= ~MS_REC; - else { - log_error("Invalid bind mount option: %s", word); - return -EINVAL; - } - } - - *mount_flags = flags; - /* in the future mount_opts will hold string options for mount(2) */ - *mount_opts = opts; - - return 0; -} - static int mount_bind(const char *dest, CustomMount *m) { - _cleanup_free_ char *mount_opts = NULL, *where = NULL; - unsigned long mount_flags = MS_BIND | MS_REC; + _cleanup_free_ char *where = NULL; struct stat source_st, dest_st; int r; assert(dest); assert(m); - if (m->options) { - r = parse_mount_bind_options(m->options, &mount_flags, &mount_opts); - if (r < 0) - return r; - } - if (stat(m->source, &source_st) < 0) return log_error_errno(errno, "Failed to stat %s: %m", m->source); @@ -726,7 +685,7 @@ static int mount_bind(const char *dest, CustomMount *m) { } - r = mount_verbose(LOG_ERR, m->source, where, NULL, mount_flags, mount_opts); + r = mount_verbose(LOG_ERR, m->source, where, NULL, MS_BIND | MS_REC, m->options); if (r < 0) return r; diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index b08bcd988a..2dee5f8ec8 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -23,13 +23,16 @@ #include <unistd.h> #include "alloc-util.h" +#include "def.h" #include "errno.h" #include "fd-util.h" +#include "fileio.h" #include "mkdir.h" #include "nspawn-setuid.h" #include "process-util.h" #include "signal-util.h" #include "string-util.h" +#include "strv.h" #include "user-util.h" #include "util.h" @@ -45,33 +48,18 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { return log_error_errno(errno, "Failed to allocate pipe: %m"); r = safe_fork("(getent)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid); - if (r < 0) + if (r < 0) { + safe_close_pair(pipe_fds); return r; + } if (r == 0) { - int nullfd; char *empty_env = NULL; - if (dup3(pipe_fds[1], STDOUT_FILENO, 0) < 0) - _exit(EXIT_FAILURE); - - if (pipe_fds[0] > 2) - safe_close(pipe_fds[0]); - if (pipe_fds[1] > 2) - safe_close(pipe_fds[1]); + safe_close(pipe_fds[0]); - nullfd = open("/dev/null", O_RDWR); - if (nullfd < 0) + if (rearrange_stdio(-1, pipe_fds[1], -1) < 0) _exit(EXIT_FAILURE); - if (dup3(nullfd, STDIN_FILENO, 0) < 0) - _exit(EXIT_FAILURE); - - if (dup3(nullfd, STDERR_FILENO, 0) < 0) - _exit(EXIT_FAILURE); - - if (nullfd > 2) - safe_close(nullfd); - close_all_fds(NULL, 0); execle("/usr/bin/getent", "getent", database, key, NULL, &empty_env); @@ -87,10 +75,10 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { } int change_uid_gid(const char *user, char **_home) { - char line[LINE_MAX], *x, *u, *g, *h; + char *x, *u, *g, *h; const char *word, *state; _cleanup_free_ uid_t *uids = NULL; - _cleanup_free_ char *home = NULL; + _cleanup_free_ char *home = NULL, *line = NULL; _cleanup_fclose_ FILE *f = NULL; _cleanup_close_ int fd = -1; unsigned n_uids = 0; @@ -102,7 +90,7 @@ int change_uid_gid(const char *user, char **_home) { assert(_home); - if (!user || streq(user, "root") || streq(user, "0")) { + if (!user || STR_IN_SET(user, "root", "0")) { /* Reset everything fully to 0, just in case */ r = reset_uid_gid(); @@ -118,21 +106,18 @@ int change_uid_gid(const char *user, char **_home) { if (fd < 0) return fd; - f = fdopen(fd, "r"); + f = fdopen(fd, "re"); if (!f) return log_oom(); fd = -1; - if (!fgets(line, sizeof(line), f)) { - if (!ferror(f)) { - log_error("Failed to resolve user %s.", user); - return -ESRCH; - } - - return log_error_errno(errno, "Failed to read from getent: %m"); + r = read_line(f, LONG_LINE_MAX, &line); + if (r == 0) { + log_error("Failed to resolve user %s.", user); + return -ESRCH; } - - truncate_nl(line); + if (r < 0) + return log_error_errno(r, "Failed to read from getent: %m"); (void) wait_for_terminate_and_check("getent passwd", pid, WAIT_LOG); @@ -195,27 +180,26 @@ int change_uid_gid(const char *user, char **_home) { if (!home) return log_oom(); + f = safe_fclose(f); + line = mfree(line); + /* Second, get group memberships */ fd = spawn_getent("initgroups", user, &pid); if (fd < 0) return fd; - fclose(f); - f = fdopen(fd, "r"); + f = fdopen(fd, "re"); if (!f) return log_oom(); fd = -1; - if (!fgets(line, sizeof(line), f)) { - if (!ferror(f)) { - log_error("Failed to resolve user %s.", user); - return -ESRCH; - } - - return log_error_errno(errno, "Failed to read from getent: %m"); + r = read_line(f, LONG_LINE_MAX, &line); + if (r == 0) { + log_error("Failed to resolve user %s.", user); + return -ESRCH; } - - truncate_nl(line); + if (r < 0) + return log_error_errno(r, "Failed to read from getent: %m"); (void) wait_for_terminate_and_check("getent initgroups", pid, WAIT_LOG); @@ -234,10 +218,8 @@ int change_uid_gid(const char *user, char **_home) { return log_oom(); r = parse_uid(c, &uids[n_uids++]); - if (r < 0) { - log_error("Failed to parse group data from getent."); - return -EIO; - } + if (r < 0) + return log_error_errno(r, "Failed to parse group data from getent: %m"); } r = mkdir_parents(home, 0775); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 0f05ecff03..90f1c4184f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2233,10 +2233,8 @@ static int chase_symlinks_and_update(char **p, unsigned flags) { if (r < 0) return log_error_errno(r, "Failed to resolve path %s: %m", *p); - free(*p); - *p = chased; - - return 0; + free_and_replace(*p, chased); + return r; /* r might be an fd here in case we ever use CHASE_OPEN in flags */ } static int determine_uid_shift(const char *directory) { @@ -2584,23 +2582,15 @@ static int outer_child( return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m"); if (interactive) { - close_nointr(STDIN_FILENO); - close_nointr(STDOUT_FILENO); - close_nointr(STDERR_FILENO); - - r = open_terminal(console, O_RDWR); - if (r != STDIN_FILENO) { - if (r >= 0) { - safe_close(r); - r = -EINVAL; - } + int terminal; - return log_error_errno(r, "Failed to open console: %m"); - } + terminal = open_terminal(console, O_RDWR); + if (terminal < 0) + return log_error_errno(terminal, "Failed to open console: %m"); - if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO || - dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) - return log_error_errno(errno, "Failed to duplicate console: %m"); + r = rearrange_stdio(terminal, terminal, terminal); /* invalidates 'terminal' on success and failure */ + if (r < 0) + return log_error_errno(r, "Failed to move console to stdin/stdout/stderr: %m"); } r = reset_audit_loginuid(); |