X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=4d4091940f9e13018940d2beaf1bcb59116563f6;hb=401cc72da8e59a1e49acafee69280f7ebaa52e74;hp=271c57f562186974fcde25e0c76b5afb99a8c5b8;hpb=68faf98ca09314b61314ad2ac0cc133c400a83f9;p=elogind.git diff --git a/src/core/execute.c b/src/core/execute.c index 271c57f56..4d4091940 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef HAVE_PAM #include @@ -58,6 +59,7 @@ #include "utmp-wtmp.h" #include "def.h" #include "loopback-setup.h" +#include "path-util.h" /* This assumes there is a 'tty' group */ #define TTY_MODE 0620 @@ -701,6 +703,7 @@ static int null_conv( static int setup_pam( const char *name, const char *user, + uid_t uid, const char *tty, char ***pam_env, int fds[], unsigned n_fds) { @@ -779,10 +782,17 @@ static int setup_pam( open here that have been opened by PAM. */ close_many(fds, n_fds); - /* Wait until our parent died. This will most likely - * not work since the kernel does not allow - * unprivileged parents kill their privileged children - * this way. We rely on the control groups kill logic + /* Drop privileges - we don't need any to pam_close_session + * and this will make PR_SET_PDEATHSIG work in most cases. + * If this fails, ignore the error - but expect sd-pam threads + * to fail to exit normally */ + if (setresuid(uid, uid, uid) < 0) + log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r)); + + /* Wait until our parent died. This will only work if + * the above setresuid() succeeds, otherwise the kernel + * will not allow unprivileged parents kill their privileged + * children this way. We rely on the control groups kill logic * to do the rest for us. */ if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) goto child_finish; @@ -928,7 +938,7 @@ static void rename_process_from_path(const char *path) { /* This resulting string must fit in 10 chars (i.e. the length * of "/sbin/init") to look pretty in /bin/ps */ - p = file_name_from_path(path); + p = path_get_file_name(path); if (isempty(p)) { rename_process("(...)"); return; @@ -962,6 +972,8 @@ int exec_spawn(ExecCommand *command, bool confirm_spawn, CGroupBonding *cgroup_bondings, CGroupAttribute *cgroup_attributes, + const char *cgroup_suffix, + int idle_pipe[2], pid_t *ret) { pid_t pid; @@ -1049,6 +1061,15 @@ int exec_spawn(ExecCommand *command, goto fail_child; } + if (idle_pipe) { + if (idle_pipe[1] >= 0) + close_nointr_nofail(idle_pipe[1]); + if (idle_pipe[0] >= 0) { + fd_wait_for_event(idle_pipe[0], POLLHUP, DEFAULT_TIMEOUT_USEC); + close_nointr_nofail(idle_pipe[0]); + } + } + /* Close sockets very early to make sure we don't * block init reexecution because it cannot bind its * sockets */ @@ -1140,21 +1161,21 @@ int exec_spawn(ExecCommand *command, } if (!keep_stdout) { - err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + err = setup_output(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin); if (err < 0) { r = EXIT_STDOUT; goto fail_child; } } - err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + err = setup_error(context, socket_fd, path_get_file_name(command->path), apply_tty_stdin); if (err < 0) { r = EXIT_STDERR; goto fail_child; } if (cgroup_bondings) { - err = cgroup_bonding_install_list(cgroup_bondings, 0); + err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix); if (err < 0) { r = EXIT_CGROUP; goto fail_child; @@ -1281,7 +1302,7 @@ int exec_spawn(ExecCommand *command, #ifdef HAVE_PAM if (context->pam_name && username) { - err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds); + err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); if (err < 0) { r = EXIT_PAM; goto fail_child; @@ -1505,7 +1526,7 @@ int exec_spawn(ExecCommand *command, * sure that when we kill the cgroup the process will be * killed too). */ if (cgroup_bondings) - cgroup_bonding_install_list(cgroup_bondings, pid); + cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); log_debug("Forked %s as %lu", command->path, (unsigned long) pid);