diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-02-09 00:58:43 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-02-09 01:00:21 +0100 |
commit | 7f6d613516020bf390d8de25bbbb2551ea8dade0 (patch) | |
tree | d55fd33c0f105956341796e1f625c99f2816764d | |
parent | cd3f8b7ddb052ab5e4eab420968bae689db3899a (diff) |
systemctl: make sure the tty agent does not retain a copy of stdio
https://bugzilla.redhat.com/show_bug.cgi?id=674916
-rw-r--r-- | TODO | 14 | ||||
-rw-r--r-- | src/systemctl.c | 29 | ||||
-rw-r--r-- | src/tty-ask-password-agent.c | 2 |
3 files changed, 43 insertions, 2 deletions
@@ -14,6 +14,20 @@ Bugs: Features: +* make it possible to enable status msgs via RT sigs + +* udisks should not use udisks-part-id, instead use blkid. also not probe /dev/loopxxx + +* snd-seq muss weg + +* mount.tmpfs soll weg und grep weg + +* mdmon is irre + +* gnome-shell python script/glxinfo/is-accelerated wech + +* plymouth muss sauber exiten, wenn's schon läuft + * pull in by udev change event instead of only start event * PID heuristik bei Type=forking ausmachbar machen diff --git a/src/systemctl.c b/src/systemctl.c index 8cdc01aa49..66903aba28 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -151,13 +151,15 @@ static void spawn_ask_password_agent(void) { if (child == 0) { /* In the child */ - const char * const args[] = { SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL }; + int fd; + + /* Make sure the agent goes away when the parent dies */ if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) _exit(EXIT_FAILURE); @@ -166,6 +168,31 @@ static void spawn_ask_password_agent(void) { if (getppid() != parent) _exit(EXIT_SUCCESS); + /* Don't leak fds to the agent */ + close_all_fds(NULL, 0); + + /* Detach from stdin/stdout/stderr. and reopen + * /dev/tty for them. This is important to ensure that + * when systemctl is started via popen() or a similar + * call that expects to read EOF we actually do + * generate EOF and not delay this indefinitely by + * because we keep an unused copy of stdin around. */ + if ((fd = open("/dev/tty", O_RDWR|O_CLOEXEC|O_NONBLOCK)) < 0) { + log_error("Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + if (fd > 2) + close(fd); + execv(args[0], (char **) args); _exit(EXIT_FAILURE); } diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c index c3c5f7a8b6..00496e7119 100644 --- a/src/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent.c @@ -83,7 +83,7 @@ static int ask_password_plymouth(const char *message, usec_t until, const char * sa.sa.sa_family = AF_UNIX; strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { - log_error("FIALED TO CONNECT: %m"); + log_error("FAILED TO CONNECT: %m"); r = -errno; goto finish; } |