X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=bc876a32920270febcd25a4c66c0cef3e9f8d2ef;hb=8e70580bb07ae46dc0b0bf377de6333540668acc;hp=b28962a3c342a5073b1b7dc366be7a0a4150d795;hpb=80cbda3558c534b575bf5315fa53b0f82dc088ab;p=elogind.git diff --git a/src/core/execute.c b/src/core/execute.c index b28962a3c..bc876a329 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -40,6 +40,7 @@ #include #include #include +#include #ifdef HAVE_PAM #include @@ -165,6 +166,26 @@ void exec_context_tty_reset(const ExecContext *context) { vt_disallocate(context->tty_path); } +static bool is_terminal_output(ExecOutput o) { + return + o == EXEC_OUTPUT_TTY || + o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || + o == EXEC_OUTPUT_KMSG_AND_CONSOLE || + o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE; +} + +void exec_context_serialize(const ExecContext *context, Unit *u, FILE *f) { + assert(context); + assert(u); + assert(f); + + if (context->tmp_dir) + unit_serialize_item(u, f, "tmp-dir", context->tmp_dir); + + if (context->var_tmp_dir) + unit_serialize_item(u, f, "var-tmp-dir", context->var_tmp_dir); +} + static int open_null_as(int flags, int nfd) { int fd, r; @@ -224,7 +245,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons !!context->syslog_level_prefix, output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE, output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE, - output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || output == EXEC_OUTPUT_KMSG_AND_CONSOLE || output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE); + is_terminal_output(output)); if (fd != nfd) { r = dup2(fd, nfd) < 0 ? -errno : nfd; @@ -960,7 +981,7 @@ static int apply_seccomp(uint32_t *syscall_filter) { int exec_spawn(ExecCommand *command, char **argv, - const ExecContext *context, + ExecContext *context, int fds[], unsigned n_fds, char **environment, bool apply_permissions, @@ -1028,6 +1049,12 @@ int exec_spawn(ExecCommand *command, cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings); + if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) { + r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir); + if (r < 0) + return r; + } + pid = fork(); if (pid < 0) return -errno; @@ -1294,6 +1321,8 @@ int exec_spawn(ExecCommand *command, err = setup_namespace(context->read_write_dirs, context->read_only_dirs, context->inaccessible_dirs, + context->tmp_dir, + context->var_tmp_dir, context->private_tmp, context->mount_flags); if (err < 0) { @@ -1522,7 +1551,26 @@ void exec_context_init(ExecContext *c) { c->timer_slack_nsec = (nsec_t) -1; } -void exec_context_done(ExecContext *c) { +void exec_context_tmp_dirs_done(ExecContext *c) { + char* dirs[] = {c->tmp_dir ? c->tmp_dir : c->var_tmp_dir, + c->tmp_dir ? c->var_tmp_dir : NULL, + NULL}; + char **dirp; + + for(dirp = dirs; *dirp; dirp++) { + char *dir; + rm_rf_dangerous(*dirp, false, true, false); + + dir = dirname(*dirp); + rmdir(dir); + + free(*dirp); + } + + c->tmp_dir = c->var_tmp_dir = NULL; +} + +void exec_context_done(ExecContext *c, bool reloading_or_reexecuting) { unsigned l; assert(c); @@ -1586,6 +1634,9 @@ void exec_context_done(ExecContext *c) { free(c->syscall_filter); c->syscall_filter = NULL; + + if (!reloading_or_reexecuting) + exec_context_tmp_dirs_done(c); } void exec_command_done(ExecCommand *c) { @@ -1710,6 +1761,37 @@ int exec_context_load_environment(const ExecContext *c, char ***l) { return 0; } +static bool tty_may_match_dev_console(const char *tty) { + char *active = NULL, *console; + bool b; + + if (startswith(tty, "/dev/")) + tty += 5; + + /* trivial identity? */ + if (streq(tty, "console")) + return true; + + console = resolve_dev_console(&active); + /* if we could not resolve, assume it may */ + if (!console) + return true; + + /* "tty0" means the active VC, so it may be the same sometimes */ + b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty)); + free(active); + + return b; +} + +bool exec_context_may_touch_console(ExecContext *ec) { + return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate || + is_terminal_input(ec->std_input) || + is_terminal_output(ec->std_output) || + is_terminal_output(ec->std_error)) && + tty_may_match_dev_console(tty_path(ec)); +} + static void strv_fprintf(FILE *f, char **l) { char **g;