From 71ec74d19332378dca8a6a7eb30411e08978f9a6 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 6 Jun 2019 14:05:27 +0200 Subject: [PATCH 1/6] fs-util: no need for fchmod_and_chown() to access /proc/self/fd directly fstat(2) is fine with O_PATH fds. For changing owership of a file opened with O_PATH, there's fchownat(2). Only changing permissions is problematic but we introduced fchmod_opath() for that purpose. --- src/basic/fs-util.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 7dfc1b309d9..14d37257099 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -226,7 +226,6 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { } int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) { - char fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; bool do_chown, do_chmod; struct stat st; @@ -236,11 +235,9 @@ int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) { * unaffected if the uid/gid is changed, i.e. it undoes implicit suid/sgid dropping the kernel does * on chown(). * - * This call is happy with O_PATH fds, since we always go via /proc/self/fd/ to change - * ownership/access mode. */ + * This call is happy with O_PATH fds. */ - xsprintf(fd_path, "/proc/self/fd/%i", fd); - if (stat(fd_path, &st) < 0) + if (fstat(fd, &st) < 0) return -errno; do_chown = @@ -262,16 +259,16 @@ int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) { mode_t minimal = st.st_mode & mode; /* the subset of the old and the new mask */ if (((minimal ^ st.st_mode) & 07777) != 0) - if (chmod(fd_path, minimal & 07777) < 0) + if (fchmod_opath(fd, minimal & 07777) < 0) return -errno; } if (do_chown) - if (chown(fd_path, uid, gid) < 0) + if (fchownat(fd, "", uid, gid, AT_EMPTY_PATH) < 0) return -errno; if (do_chmod) - if (chmod(fd_path, mode & 07777) < 0) + if (fchmod_opath(fd, mode & 07777) < 0) return -errno; return do_chown || do_chmod; From 04c84cd173d61cfd601405d717b6605ef6651206 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Fri, 7 Jun 2019 07:36:11 +0200 Subject: [PATCH 2/6] namespace-util: make use of TAKE_FD() No functional changes. --- src/basic/namespace-util.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c index 67bdaa19d5e..1fc593df409 100644 --- a/src/basic/namespace-util.c +++ b/src/basic/namespace-util.c @@ -62,21 +62,19 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int * } if (pidns_fd) - *pidns_fd = pidnsfd; + *pidns_fd = TAKE_FD(pidnsfd); if (mntns_fd) - *mntns_fd = mntnsfd; + *mntns_fd = TAKE_FD(mntnsfd); if (netns_fd) - *netns_fd = netnsfd; + *netns_fd = TAKE_FD(netnsfd); if (userns_fd) - *userns_fd = usernsfd; + *userns_fd = TAKE_FD(usernsfd); if (root_fd) - *root_fd = rfd; - - pidnsfd = mntnsfd = netnsfd = usernsfd = -1; + *root_fd = TAKE_FD(rfd); return 0; } From ba72801d660a02429b6a0658db2dadfbe25bde04 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 6 Jun 2019 15:58:14 +0200 Subject: [PATCH 3/6] nspawn: use correct error variable when logging errors returned by send_one_fd() --- src/nspawn/nspawn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 25184e11e9e..3713daa1fbf 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3438,7 +3438,7 @@ static int outer_child( l = send_one_fd(notify_socket, fd, 0); if (l < 0) - return log_error_errno(errno, "Failed to send notify fd: %m"); + return log_error_errno(l, "Failed to send notify fd: %m"); pid_socket = safe_close(pid_socket); uuid_socket = safe_close(uuid_socket); From 3acc84ebd9aebe8cf1771b42644ebbfbecdfaa37 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Thu, 6 Jun 2019 10:05:33 +0200 Subject: [PATCH 4/6] nspawn: allocate the pty used for /dev/console within the container The console tty is now allocated from within the container so it's not necessary anymore to allocate it from the host and bind mount the pty slave into the container. The pty master is sent to the host. /dev/console is now a symlink pointing to the pty slave. This might also be less confusing for applications running inside the container and the overall result looks cleaner (we don't need to apply manually the passed selinux context, if any, to the allocated pty for instance). --- TODO | 3 - src/nspawn/nspawn.c | 198 ++++++++++++++++++++++++-------------------- 2 files changed, 108 insertions(+), 93 deletions(-) diff --git a/TODO b/TODO index 57c07bea7ae..3f69c24fc36 100644 --- a/TODO +++ b/TODO @@ -209,9 +209,6 @@ Features: /etc/resolv.conf. Should be smart and do something useful on read-only images, for example fallback to read-only bind mounting the file instead. -* nspawn's console TTY should be allocated from within the container, not - mounted in from the outside - * show invocation ID in systemd-run output * bypass SIGTERM state in unit files if KillSignal is SIGKILL diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 3713daa1fbf..085a9806ce4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2037,32 +2037,41 @@ static int setup_pts(const char *dest) { return 0; } -static int setup_dev_console(const char *dest, const char *console) { - _cleanup_umask_ mode_t u; - const char *to; +static int setup_stdio_as_dev_console(void) { + int terminal; int r; - assert(dest); + terminal = open_terminal("/dev/console", O_RDWR); + if (terminal < 0) + return log_error_errno(terminal, "Failed to open console: %m"); - u = umask(0000); - - if (!console) - return 0; - - r = chmod_and_chown(console, 0600, arg_uid_shift, arg_uid_shift); + /* Make sure we can continue logging to the original stderr, even if + * stderr points elsewhere now */ + r = log_dup_console(); if (r < 0) - return log_error_errno(r, "Failed to correct access mode for TTY: %m"); + return log_error_errno(r, "Failed to duplicate stderr: %m"); - /* We need to bind mount the right tty to /dev/console since - * ptys can only exist on pts file systems. To have something - * to bind mount things on we create a empty regular file. */ - - to = prefix_roota(dest, "/dev/console"); - r = touch(to); + /* invalidates 'terminal' on success and failure */ + r = rearrange_stdio(terminal, terminal, terminal); if (r < 0) - return log_error_errno(r, "touch() for /dev/console failed: %m"); + return log_error_errno(r, "Failed to move console to stdin/stdout/stderr: %m"); - return mount_verbose(LOG_ERR, console, to, NULL, MS_BIND, NULL); + return 0; +} + +static int setup_dev_console(const char *console) { + _cleanup_free_ char *p = NULL; + int r; + + /* Create /dev/console symlink */ + r = path_make_relative("/dev", console, &p); + if (r < 0) + return log_error_errno(r, "Failed to create relative path: %m"); + + if (symlink(p, "/dev/console") < 0) + return log_error_errno(errno, "Failed to create /dev/console symlink: %m"); + + return 0; } static int setup_keyring(void) { @@ -2775,8 +2784,10 @@ static int inner_child( bool secondary, int kmsg_socket, int rtnl_socket, + int master_pty_socket, FDSet *fds) { + _cleanup_close_ int master = -1; _cleanup_free_ char *home = NULL; char as_uuid[37]; size_t n_env = 1; @@ -2908,6 +2919,36 @@ static int inner_child( rtnl_socket = safe_close(rtnl_socket); } + if (arg_console_mode != CONSOLE_PIPE) { + _cleanup_free_ char *console = NULL; + + /* Allocate a pty and make it available as /dev/console. */ + + master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); + if (master < 0) + return log_error_errno(errno, "Failed to acquire pseudo tty: %m"); + + r = ptsname_malloc(master, &console); + if (r < 0) + return log_error_errno(r, "Failed to determine tty name: %m"); + + if (unlockpt(master) < 0) + return log_error_errno(errno, "Failed to unlock tty: %m"); + + r = setup_dev_console(console); + if (r < 0) + return log_error_errno(r, "Failed to setup /dev/console: %m"); + + r = send_one_fd(master_pty_socket, master, 0); + if (r < 0) + return log_error_errno(r, "Failed to send master fd: %m"); + master_pty_socket = safe_close(master_pty_socket); + + r = setup_stdio_as_dev_console(); + if (r < 0) + return r; + } + r = patch_sysctl(); if (r < 0) return r; @@ -3129,7 +3170,6 @@ static int setup_sd_notify_child(void) { static int outer_child( Barrier *barrier, const char *directory, - const char *console, DissectedImage *dissected_image, bool secondary, int pid_socket, @@ -3138,6 +3178,7 @@ static int outer_child( int kmsg_socket, int rtnl_socket, int uid_shift_socket, + int master_pty_socket, int unified_cgroup_hierarchy_socket, FDSet *fds, int netns_fd) { @@ -3157,6 +3198,7 @@ static int outer_child( assert(pid_socket >= 0); assert(uuid_socket >= 0); assert(notify_socket >= 0); + assert(master_pty_socket >= 0); assert(kmsg_socket >= 0); log_debug("Outer child is initializing."); @@ -3164,25 +3206,6 @@ static int outer_child( if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m"); - if (arg_console_mode != CONSOLE_PIPE) { - int terminal; - - assert(console); - - terminal = open_terminal(console, O_RDWR); - if (terminal < 0) - return log_error_errno(terminal, "Failed to open console: %m"); - - /* Make sure we can continue logging to the original stderr, even if stderr points elsewhere now */ - r = log_dup_console(); - if (r < 0) - return log_error_errno(r, "Failed to duplicate stderr: %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(); if (r < 0) return r; @@ -3337,10 +3360,6 @@ static int outer_child( if (r < 0) return r; - r = setup_dev_console(directory, console); - if (r < 0) - return r; - r = setup_keyring(); if (r < 0) return r; @@ -3415,7 +3434,7 @@ static int outer_child( return log_error_errno(r, "Failed to join network namespace: %m"); } - r = inner_child(barrier, directory, secondary, kmsg_socket, rtnl_socket, fds); + r = inner_child(barrier, directory, secondary, kmsg_socket, rtnl_socket, master_pty_socket, fds); if (r < 0) _exit(EXIT_FAILURE); @@ -3443,6 +3462,7 @@ static int outer_child( pid_socket = safe_close(pid_socket); uuid_socket = safe_close(uuid_socket); notify_socket = safe_close(notify_socket); + master_pty_socket = safe_close(master_pty_socket); kmsg_socket = safe_close(kmsg_socket); rtnl_socket = safe_close(rtnl_socket); netns_fd = safe_close(netns_fd); @@ -4042,14 +4062,13 @@ static int load_oci_bundle(void) { return merge_settings(settings, arg_oci_bundle); } -static int run_container(int master, - const char* console, +static int run_container( DissectedImage *dissected_image, bool secondary, FDSet *fds, char veth_name[IFNAMSIZ], bool *veth_created, union in_addr_union *exposed, - pid_t *pid, int *ret) { + int *master, pid_t *pid, int *ret) { static const struct sigaction sa = { .sa_handler = nop_signal_handler, @@ -4065,9 +4084,10 @@ static int run_container(int master, uuid_socket_pair[2] = { -1, -1 }, notify_socket_pair[2] = { -1, -1 }, uid_shift_socket_pair[2] = { -1, -1 }, + master_pty_socket_pair[2] = { -1, -1 }, unified_cgroup_hierarchy_socket_pair[2] = { -1, -1}; - _cleanup_close_ int notify_socket= -1; + _cleanup_close_ int notify_socket = -1; _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL; _cleanup_(sd_event_source_unrefp) sd_event_source *notify_event_source = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; @@ -4115,6 +4135,9 @@ static int run_container(int master, if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, notify_socket_pair) < 0) return log_error_errno(errno, "Failed to create notify socket pair: %m"); + if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, master_pty_socket_pair) < 0) + return log_error_errno(errno, "Failed to create console socket pair: %m"); + if (arg_userns_mode != USER_NAMESPACE_NO) if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, uid_shift_socket_pair) < 0) return log_error_errno(errno, "Failed to create uid shift socket pair: %m"); @@ -4158,13 +4181,12 @@ static int run_container(int master, /* The outer child only has a file system namespace. */ barrier_set_role(&barrier, BARRIER_CHILD); - master = safe_close(master); - kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]); rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]); pid_socket_pair[0] = safe_close(pid_socket_pair[0]); uuid_socket_pair[0] = safe_close(uuid_socket_pair[0]); notify_socket_pair[0] = safe_close(notify_socket_pair[0]); + master_pty_socket_pair[0] = safe_close(master_pty_socket_pair[0]); uid_shift_socket_pair[0] = safe_close(uid_shift_socket_pair[0]); unified_cgroup_hierarchy_socket_pair[0] = safe_close(unified_cgroup_hierarchy_socket_pair[0]); @@ -4173,7 +4195,6 @@ static int run_container(int master, r = outer_child(&barrier, arg_directory, - console, dissected_image, secondary, pid_socket_pair[1], @@ -4182,6 +4203,7 @@ static int run_container(int master, kmsg_socket_pair[1], rtnl_socket_pair[1], uid_shift_socket_pair[1], + master_pty_socket_pair[1], unified_cgroup_hierarchy_socket_pair[1], fds, netns_fd); @@ -4200,6 +4222,7 @@ static int run_container(int master, pid_socket_pair[1] = safe_close(pid_socket_pair[1]); uuid_socket_pair[1] = safe_close(uuid_socket_pair[1]); notify_socket_pair[1] = safe_close(notify_socket_pair[1]); + master_pty_socket_pair[1] = safe_close(master_pty_socket_pair[1]); uid_shift_socket_pair[1] = safe_close(uid_shift_socket_pair[1]); unified_cgroup_hierarchy_socket_pair[1] = safe_close(unified_cgroup_hierarchy_socket_pair[1]); @@ -4474,17 +4497,40 @@ static int run_container(int master, rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]); - if (IN_SET(arg_console_mode, CONSOLE_INTERACTIVE, CONSOLE_READ_ONLY)) { - assert(master >= 0); + if (arg_console_mode != CONSOLE_PIPE) { + _cleanup_close_ int fd = -1; + PTYForwardFlags flags = 0; - r = pty_forward_new(event, master, - PTY_FORWARD_IGNORE_VHANGUP | (arg_console_mode == CONSOLE_READ_ONLY ? PTY_FORWARD_READ_ONLY : 0), - &forward); - if (r < 0) - return log_error_errno(r, "Failed to create PTY forwarder: %m"); + /* Retrieve the master pty allocated by inner child */ + fd = receive_one_fd(master_pty_socket_pair[0], 0); + if (fd < 0) + return log_error_errno(fd, "Failed to receive master pty from the inner child: %m"); - if (arg_console_width != (unsigned) -1 || arg_console_height != (unsigned) -1) - (void) pty_forward_set_width_height(forward, arg_console_width, arg_console_height); + switch (arg_console_mode) { + + case CONSOLE_READ_ONLY: + flags |= PTY_FORWARD_READ_ONLY; + + _fallthrough_; + + case CONSOLE_INTERACTIVE: + flags |= PTY_FORWARD_IGNORE_VHANGUP; + + r = pty_forward_new(event, fd, flags, &forward); + if (r < 0) + return log_error_errno(r, "Failed to create PTY forwarder: %m"); + + if (arg_console_width != (unsigned) -1 || arg_console_height != (unsigned) -1) + (void) pty_forward_set_width_height(forward, + arg_console_width, + arg_console_height); + break; + + default: + assert(arg_console_mode == CONSOLE_PASSIVE); + } + + *master = TAKE_FD(fd); } r = sd_event_loop(event); @@ -4614,7 +4660,6 @@ static int initialize_rlimits(void) { } static int run(int argc, char *argv[]) { - _cleanup_free_ char *console = NULL; _cleanup_close_ int master = -1; _cleanup_fdset_free_ FDSet *fds = NULL; int r, n_fd_passed, ret = EXIT_SUCCESS; @@ -4929,31 +4974,6 @@ static int run(int argc, char *argv[]) { if (arg_console_mode == CONSOLE_PIPE) /* if we pass STDERR on to the container, don't add our own logs into it too */ arg_quiet = true; - if (arg_console_mode != CONSOLE_PIPE) { - master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); - if (master < 0) { - r = log_error_errno(errno, "Failed to acquire pseudo tty: %m"); - goto finish; - } - - r = ptsname_malloc(master, &console); - if (r < 0) { - r = log_error_errno(r, "Failed to determine tty name: %m"); - goto finish; - } - - if (arg_selinux_apifs_context) { - r = mac_selinux_apply(console, arg_selinux_apifs_context); - if (r < 0) - goto finish; - } - - if (unlockpt(master) < 0) { - r = log_error_errno(errno, "Failed to unlock tty: %m"); - goto finish; - } - } - if (!arg_quiet) log_info("Spawning container %s on %s.\nPress ^] three times within 1s to kill container.", arg_machine, arg_image ?: arg_directory); @@ -4966,13 +4986,11 @@ static int run(int argc, char *argv[]) { } for (;;) { - r = run_container(master, - console, - dissected_image, + r = run_container(dissected_image, secondary, fds, veth_name, &veth_created, - &exposed, + &exposed, &master, &pid, &ret); if (r <= 0) break; From ae1d13db056ee139f89fbb7cbc893dc5d89ffde3 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Fri, 7 Jun 2019 10:17:11 +0200 Subject: [PATCH 5/6] terminal-util: introduce openpt_allocate() Allocating a pty is done in a couple of places so let's introduce a new helper which does the job. Also the new function, as well as openpt_in_namespace(), returns both pty master and slave so the callers don't need to know about the pty slave allocation details. For the same reasons machine_openpt() prototype has also been changed to return both pty master and slave so callers don't need to allocate a pty slave which might be in a different namespace. Finally openpt_in_namespace() has been renamed into openpt_allocate_in_namespace(). --- src/basic/terminal-util.c | 56 ++++++++++++++++++++++++++++++-------- src/basic/terminal-util.h | 4 +-- src/machine/machine-dbus.c | 21 +++----------- src/machine/machine.c | 17 +++--------- src/machine/machine.h | 2 +- 5 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 3a0d16a74f5..aa69bede6f5 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -1049,7 +1049,34 @@ int ptsname_malloc(int fd, char **ret) { } } -int ptsname_namespace(int pty, char **ret) { +int openpt_allocate(int flags, char **ret_slave) { + _cleanup_close_ int fd = -1; + _cleanup_free_ char *p = NULL; + int r; + + fd = posix_openpt(flags|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ret_slave) { + r = ptsname_malloc(fd, &p); + if (r < 0) + return r; + + if (!path_startswith(p, "/dev/pts/")) + return -EINVAL; + } + + if (unlockpt(fd) < 0) + return -errno; + + if (ret_slave) + *ret_slave = TAKE_PTR(p); + + return TAKE_FD(fd); +} + +static int ptsname_namespace(int pty, char **ret) { int no = -1, r; /* Like ptsname(), but doesn't assume that the path is @@ -1068,8 +1095,8 @@ int ptsname_namespace(int pty, char **ret) { return 0; } -int openpt_in_namespace(pid_t pid, int flags) { - _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1; +int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave) { + _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1, fd = -1; _cleanup_close_pair_ int pair[2] = { -1, -1 }; pid_t child; int r; @@ -1088,18 +1115,13 @@ int openpt_in_namespace(pid_t pid, int flags) { if (r < 0) return r; if (r == 0) { - int master; - pair[0] = safe_close(pair[0]); - master = posix_openpt(flags|O_NOCTTY|O_CLOEXEC); - if (master < 0) + fd = openpt_allocate(flags, NULL); + if (fd < 0) _exit(EXIT_FAILURE); - if (unlockpt(master) < 0) - _exit(EXIT_FAILURE); - - if (send_one_fd(pair[1], master, 0) < 0) + if (send_one_fd(pair[1], fd, 0) < 0) _exit(EXIT_FAILURE); _exit(EXIT_SUCCESS); @@ -1113,7 +1135,17 @@ int openpt_in_namespace(pid_t pid, int flags) { if (r != EXIT_SUCCESS) return -EIO; - return receive_one_fd(pair[0], 0); + fd = receive_one_fd(pair[0], 0); + if (fd < 0) + return fd; + + if (ret_slave) { + r = ptsname_namespace(fd, ret_slave); + if (r < 0) + return r; + } + + return TAKE_FD(fd); } int open_terminal_in_namespace(pid_t pid, const char *name, int mode) { diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 87d09f87598..6e5b273c75e 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -151,9 +151,9 @@ int getttyname_malloc(int fd, char **r); int getttyname_harder(int fd, char **r); int ptsname_malloc(int fd, char **ret); -int ptsname_namespace(int pty, char **ret); -int openpt_in_namespace(pid_t pid, int flags); +int openpt_allocate(int flags, char **ret_slave); +int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave); int open_terminal_in_namespace(pid_t pid, const char *name, int mode); int vt_default_utf8(void); diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 1ee878055eb..b89e6046d93 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -423,14 +423,10 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_ if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - r = sd_bus_message_new_method_return(message, &reply); if (r < 0) return r; @@ -514,17 +510,12 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - p = path_startswith(pty_name, "/dev/pts/"); - if (!p) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PTS name %s is invalid", pty_name); + assert(p); r = container_bus_new(m, error, &allocated_bus); if (r < 0) @@ -630,14 +621,10 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu if (r == 0) return 1; /* Will call us back */ - master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC); + master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); if (master < 0) return master; - r = ptsname_namespace(master, &pty_name); - if (r < 0) - return r; - p = path_startswith(pty_name, "/dev/pts/"); assert(p); diff --git a/src/machine/machine.c b/src/machine/machine.c index b916d038d7a..ef8ccd98fb2 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -530,29 +530,20 @@ int machine_kill(Machine *m, KillWho who, int signo) { return manager_kill_unit(m->manager, m->unit, signo, NULL); } -int machine_openpt(Machine *m, int flags) { +int machine_openpt(Machine *m, int flags, char **ret_slave) { assert(m); switch (m->class) { - case MACHINE_HOST: { - int fd; + case MACHINE_HOST: - fd = posix_openpt(flags); - if (fd < 0) - return -errno; - - if (unlockpt(fd) < 0) - return -errno; - - return fd; - } + return openpt_allocate(flags, ret_slave); case MACHINE_CONTAINER: if (m->leader <= 0) return -EINVAL; - return openpt_in_namespace(m->leader, flags); + return openpt_allocate_in_namespace(m->leader, flags, ret_slave); default: return -EOPNOTSUPP; diff --git a/src/machine/machine.h b/src/machine/machine.h index 9ff9a656717..f7471be8f52 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -89,7 +89,7 @@ MachineState machine_state_from_string(const char *s) _pure_; const char *kill_who_to_string(KillWho k) _const_; KillWho kill_who_from_string(const char *s) _pure_; -int machine_openpt(Machine *m, int flags); +int machine_openpt(Machine *m, int flags, char **ret_slave); int machine_open_terminal(Machine *m, const char *path, int mode); int machine_get_uid_shift(Machine *m, uid_t *ret); From dc98caea32c7eced94ad22f75ffa77753dac5b1d Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Fri, 7 Jun 2019 10:27:18 +0200 Subject: [PATCH 6/6] nspawn: make use of openpt_allocate() --- src/nspawn/nspawn.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 085a9806ce4..5079918ae15 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2923,17 +2923,9 @@ static int inner_child( _cleanup_free_ char *console = NULL; /* Allocate a pty and make it available as /dev/console. */ - - master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); + master = openpt_allocate(O_RDWR|O_NONBLOCK, &console); if (master < 0) - return log_error_errno(errno, "Failed to acquire pseudo tty: %m"); - - r = ptsname_malloc(master, &console); - if (r < 0) - return log_error_errno(r, "Failed to determine tty name: %m"); - - if (unlockpt(master) < 0) - return log_error_errno(errno, "Failed to unlock tty: %m"); + return log_error_errno(master, "Failed to allocate a pty: %m"); r = setup_dev_console(console); if (r < 0)