diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-04-13 18:50:43 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-04-13 18:50:43 +0200 |
commit | 02a51abad1d6f334599c8d648b18d000b6118eb5 (patch) | |
tree | 62bfe37786b30180d73a7426f96dbd3df3664471 | |
parent | 90a13a44cbae440d973144706aec039c7dab2e38 (diff) |
execute: chown() the tty when running owning them
-rw-r--r-- | execute.c | 35 |
1 files changed, 35 insertions, 0 deletions
@@ -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) { |