#include <sys/poll.h>
#include <linux/seccomp-bpf.h>
#include <glob.h>
+#include <libgen.h>
#ifdef HAVE_PAM
#include <security/pam_appl.h>
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;
!!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;
int exec_spawn(ExecCommand *command,
char **argv,
- const ExecContext *context,
+ ExecContext *context,
int fds[], unsigned n_fds,
char **environment,
bool apply_permissions,
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;
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) {
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);
free(c->syscall_filter);
c->syscall_filter = NULL;
+
+ if (!reloading_or_reexecuting)
+ exec_context_tmp_dirs_done(c);
}
void exec_command_done(ExecCommand *c) {
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;