Fix popen() of systemctl, #674916

This commit is contained in:
Lennart Poettering 2011-02-09 01:20:32 +01:00
parent 901be354f9
commit 1e8ec75b1e
2 changed files with 69 additions and 1 deletions

63
fix-popen.patch Normal file
View File

@ -0,0 +1,63 @@
diff --git a/src/systemctl.c b/src/systemctl.c
index 8cdc01a..c09b31d 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -141,6 +141,9 @@ static void spawn_ask_password_agent(void) {
if (!arg_ask_password)
return;
+ if (arg_user)
+ return;
+
parent = getpid();
/* Spawns a temporary TTY agent, making sure it goes away when
@@ -151,13 +154,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 +171,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)) < 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);
}

View File

@ -2,7 +2,7 @@ Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd Url: http://www.freedesktop.org/wiki/Software/systemd
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Version: 17 Version: 17
Release: 2%{?dist} Release: 3%{?dist}
License: GPLv2+ License: GPLv2+
Group: System Environment/Base Group: System Environment/Base
Summary: A System and Service Manager Summary: A System and Service Manager
@ -42,6 +42,7 @@ Obsoletes: upstart-sysvinit < 0.6.5-9
Conflicts: upstart-sysvinit Conflicts: upstart-sysvinit
Obsoletes: readahead < 1:1.5.7-3 Obsoletes: readahead < 1:1.5.7-3
Provides: readahead = 1:1.5.7-3 Provides: readahead = 1:1.5.7-3
Patch0: fix-popen.patch
%description %description
systemd is a system and service manager for Linux, compatible with systemd is a system and service manager for Linux, compatible with
@ -75,6 +76,7 @@ Graphical front-end for systemd.
%prep %prep
%setup -q %setup -q
%patch0 -p1
%build %build
%configure --with-rootdir= --with-distro=fedora %configure --with-rootdir= --with-distro=fedora
@ -229,6 +231,9 @@ fi
%{_mandir}/man1/systemadm.* %{_mandir}/man1/systemadm.*
%changelog %changelog
* Wed Feb 9 2011 Lennart Poettering <lpoetter@redhat.com> - 17-3
- Fix popen() of systemctl, #674916
* Mon Feb 7 2011 Bill Nottingham <notting@redhat.com> - 17-2 * Mon Feb 7 2011 Bill Nottingham <notting@redhat.com> - 17-2
- add epoch to readahead obsolete - add epoch to readahead obsolete