From: Lennart Poettering Date: Tue, 13 Apr 2010 16:50:43 +0000 (+0200) Subject: execute: chown() the tty when running owning them X-Git-Tag: 0.git+20100605+dfd8ee-1~128 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02a51abad1d6f334599c8d648b18d000b6118eb5;p=systemd execute: chown() the tty when running owning them --- diff --git a/execute.c b/execute.c index 5264b500..bf9a087c 100644 --- a/execute.c +++ b/execute.c @@ -44,6 +44,9 @@ #include "securebits.h" #include "cgroup.h" +/* This assumes there is a 'tty' group */ +#define TTY_MODE 0620 + static int shift_fds(int fds[], unsigned n_fds) { int start, restart_from; @@ -290,6 +293,7 @@ static int setup_output(const ExecContext *context, const char *ident) { static int setup_error(const ExecContext *context, const char *ident) { assert(context); + assert(ident); /* This expects the input and output are already set up */ @@ -326,6 +330,26 @@ static int setup_error(const ExecContext *context, const char *ident) { } } +static int chown_terminal(int fd, uid_t uid) { + struct stat st; + + assert(fd >= 0); + assert(uid >= 0); + + /* This might fail. What matters are the results. */ + fchown(fd, uid, -1); + fchmod(fd, TTY_MODE); + + if (fstat(fd, &st) < 0) + return -errno; + + if (st.st_uid != uid || + st.st_mode != TTY_MODE) + return -EPERM; + + return 0; +} + static int setup_confirm_stdio(const ExecContext *context, int *_saved_stdin, int *_saved_stdout) { @@ -354,6 +378,11 @@ static int setup_confirm_stdio(const ExecContext *context, goto fail; } + if (chown_terminal(fd, getuid()) < 0) { + r = EXIT_STDIN; + goto fail; + } + if (dup2(fd, STDIN_FILENO) < 0) { r = EXIT_STDIN; goto fail; @@ -814,6 +843,12 @@ int exec_spawn(ExecCommand *command, goto fail; } + if (is_terminal_input(context->std_input)) + if (chown_terminal(STDIN_FILENO, uid) < 0) { + r = EXIT_STDIN; + goto fail; + } + if (apply_chroot) { if (context->root_directory) if (chroot(context->root_directory) < 0) {