A System and Service Manager
CentOS Sources
2014-10-23 61b3c905370802f0a16db405747cba392b89ca79
import systemd-208-11.el7_0.4
2 files added
1 files modified
164 ■■■■■ changed files
SOURCES/0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch 86 ●●●●● patch | view | raw | blame | history
SOURCES/0236-util-reset-signals-when-we-fork-off-agents.patch 70 ●●●●● patch | view | raw | blame | history
SPECS/systemd.spec 8 ●●●● patch | view | raw | blame | history
SOURCES/0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch
New file
@@ -0,0 +1,86 @@
From c6b6b6f5ce19543e277999395252bde94f0f8d25 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 27 Aug 2014 21:42:20 +0200
Subject: [PATCH] util: fix minimal race where we might miss SIGTERMs when
 forking off an agent
Before forking, block all signals, and unblock them afterwards. This way
the child will have them blocked, and we won't lose them.
(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf)
Related: #1134818
---
 src/shared/util.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/shared/util.c b/src/shared/util.c
index 090a204..0fcc130 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4991,9 +4991,9 @@ int fd_inc_rcvbuf(int fd, size_t n) {
 }
 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
-        pid_t parent_pid, agent_pid;
-        int fd;
         bool stdout_is_tty, stderr_is_tty;
+        pid_t parent_pid, agent_pid;
+        sigset_t ss, saved_ss;
         unsigned n, i;
         va_list ap;
         char **l;
@@ -5001,16 +5001,25 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
         assert(pid);
         assert(path);
-        parent_pid = getpid();
-
         /* Spawns a temporary TTY agent, making sure it goes away when
          * we go away */
+        parent_pid = getpid();
+
+        /* First we temporarily block all signals, so that the new
+         * child has them blocked initially. This way, we can be sure
+         * that SIGTERMs are not lost we might send to the agent. */
+        assert_se(sigfillset(&ss) >= 0);
+        assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
+
         agent_pid = fork();
-        if (agent_pid < 0)
+        if (agent_pid < 0) {
+                assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
                 return -errno;
+        }
         if (agent_pid != 0) {
+                assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
                 *pid = agent_pid;
                 return 0;
         }
@@ -5021,8 +5030,14 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
         if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
                 _exit(EXIT_FAILURE);
+        /* Make sure we actually can kill the agent, if we need to, in
+         * case somebody invoked us from a shell script that trapped
+         * SIGTERM or so... */
+        reset_all_signal_handlers();
+        reset_signal_mask();
+
         /* Check whether our parent died before we were able
-         * to set the death signal */
+         * to set the death signal and unblock the signals */
         if (getppid() != parent_pid)
                 _exit(EXIT_SUCCESS);
@@ -5033,6 +5048,8 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
         stderr_is_tty = isatty(STDERR_FILENO);
         if (!stdout_is_tty || !stderr_is_tty) {
+                int fd;
+
                 /* Detach from stdout/stderr. and reopen
                  * /dev/tty for them. This is important to
                  * ensure that when systemctl is started via
SOURCES/0236-util-reset-signals-when-we-fork-off-agents.patch
New file
@@ -0,0 +1,70 @@
From 3035def5df7ee87f7eef4a29ac7e11c136d09aca Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 26 Aug 2014 21:04:21 +0200
Subject: [PATCH] util: reset signals when we fork off agents
If we invoke agents, we should make sure we actually can kill them
again. I mean, it's probably not our job to cleanup the signals if our
tools are invoked in weird contexts, but at least we should make sure,
that the subprocesses we invoke and intend to control work as intended.
Also see:
http://lists.freedesktop.org/archives/systemd-devel/2014-August/022460.html
(cherry picked from commit 8a7c93d858c342744adf481565d8bb03b9713dcf)
Resolves: #1134818
---
 src/shared/util.c | 18 ++++++++++++++++++
 src/shared/util.h |  1 +
 2 files changed, 19 insertions(+)
diff --git a/src/shared/util.c b/src/shared/util.c
index 0fcc130..3620c0a 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -935,6 +935,18 @@ int reset_all_signal_handlers(void) {
         return 0;
 }
+int reset_signal_mask(void) {
+        sigset_t ss;
+
+        if (sigemptyset(&ss) < 0)
+                return -errno;
+
+        if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
+
 char *strstrip(char *s) {
         char *e;
@@ -5044,6 +5056,12 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
         /* Don't leak fds to the agent */
         close_all_fds(except, n_except);
+        /* Make sure we actually can kill the agent, if we need to, in
+         * case somebody invoked us from a shell script that trapped
+         * SIGTERM or so... */
+        reset_all_signal_handlers();
+        reset_signal_mask();
+
         stdout_is_tty = isatty(STDOUT_FILENO);
         stderr_is_tty = isatty(STDERR_FILENO);
diff --git a/src/shared/util.h b/src/shared/util.h
index 3a4bc98..cf935ce 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -206,6 +206,7 @@ int readlink_and_make_absolute(const char *p, char **r);
 int readlink_and_canonicalize(const char *p, char **r);
 int reset_all_signal_handlers(void);
+int reset_signal_mask(void);
 char *strstrip(char *s);
 char *delete_chars(char *s, const char *bad);
SPECS/systemd.spec
@@ -11,7 +11,7 @@
Name:           systemd
Url:            http://www.freedesktop.org/wiki/Software/systemd
Version:        208
Release:        11%{?dist}.2
Release:        11%{?dist}.4
# For a breakdown of the licensing, see README
License:        LGPLv2+ and MIT and GPLv2+
Summary:        A System and Service Manager
@@ -265,6 +265,8 @@
Patch0232: 0232-logind-session-save-stopping-flag.patch
Patch0233: 0233-units-serial-getty-.service-add-Install-section.patch
Patch0234: 0234-units-order-network-online.target-after-network.targ.patch
Patch0235: 0235-util-fix-minimal-race-where-we-might-miss-SIGTERMs-w.patch
Patch0236: 0236-util-reset-signals-when-we-fork-off-agents.patch
%global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);}
@@ -1063,6 +1065,10 @@
%{_datadir}/systemd/gatewayd
%changelog
* Mon Oct 06 2014 Lukáš Nykrýn <lnykryn@redhat.com> - 208-11.4
- util: reset signals when we fork off agents
- util: fix minimal race where we might miss SIGTERMs when forking off an agent
* Mon Jul 21 2014 Lukáš Nykrýn <lnykryn@redhat.com> - 208-11.2
- units: order network-online.target after network.target