diff options
author | Balint Reczey <balint@balintreczey.hu> | 2017-02-24 01:32:27 +0100 |
---|---|---|
committer | Balint Reczey <balint@balintreczey.hu> | 2017-02-24 01:50:09 +0100 |
commit | bc6cd09194f3d289bbd1729260ae2869989e9182 (patch) | |
tree | 9929a761327325355928a848aec26d46bc41261a | |
parent | b8a7c3ac04619620f6bae08e74bc961f300fd9fb (diff) | |
download | shadow-bc6cd09194f3d289bbd1729260ae2869989e9182.tar.gz |
su: properly clear child PID (CVE-2017-2616)
Closes: #855943
-rw-r--r-- | debian/patches/0008-su-properly-clear-child-PID.patch | 60 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 61 insertions, 0 deletions
diff --git a/debian/patches/0008-su-properly-clear-child-PID.patch b/debian/patches/0008-su-properly-clear-child-PID.patch new file mode 100644 index 00000000..25f435b6 --- /dev/null +++ b/debian/patches/0008-su-properly-clear-child-PID.patch @@ -0,0 +1,60 @@ +From 08fd4b69e84364677a10e519ccb25b71710ee686 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann <tobias@stoeckmann.org> +Date: Thu, 23 Feb 2017 09:47:29 -0600 +Subject: [PATCH] su: properly clear child PID + +If su is compiled with PAM support, it is possible for any local user +to send SIGKILL to other processes with root privileges. There are +only two conditions. First, the user must be able to perform su with +a successful login. This does NOT have to be the root user, even using +su with the same id is enough, e.g. "su $(whoami)". Second, SIGKILL +can only be sent to processes which were executed after the su process. +It is not possible to send SIGKILL to processes which were already +running. I consider this as a security vulnerability, because I was +able to write a proof of concept which unlocked a screen saver of +another user this way. +--- + src/su.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/src/su.c ++++ b/src/su.c +@@ -363,11 +363,13 @@ + /* wake child when resumed */ + kill (pid, SIGCONT); + stop = false; ++ } else { ++ pid_child = 0; + } + } while (!stop); + } + +- if (0 != caught) { ++ if (0 != caught && 0 != pid_child) { + (void) fputs ("\n", stderr); + (void) fputs (_("Session terminated, terminating shell..."), + stderr); +@@ -377,9 +379,22 @@ + snprintf (wait_msg, 256, _(" ...waiting for child to terminate.\n")); + + (void) signal (SIGALRM, kill_child); ++ (void) signal (SIGCHLD, catch_signals); + (void) alarm (2); + +- (void) wait (&status); ++ sigemptyset (&ourset); ++ if ((sigaddset (&ourset, SIGALRM) != 0) ++ || (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0)) { ++ fprintf (stderr, _("%s: signal masking malfunction\n"), Prog); ++ kill_child (0); ++ } else { ++ while (0 == waitpid (pid_child, &status, WNOHANG)) { ++ sigsuspend (&ourset); ++ } ++ pid_child = 0; ++ (void) sigprocmask (SIG_UNBLOCK, &ourset, NULL); ++ } ++ + (void) fputs (_(" ...terminated.\n"), stderr); + } + diff --git a/debian/patches/series b/debian/patches/series index a2082f51..553c190b 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -5,6 +5,7 @@ 0005-Update-for-German-man-pages.patch 0006-French-manpage-translation.patch 0007-Fix-some-spelling-issues-in-the-Norwegian-translatio.patch +0008-su-properly-clear-child-PID.patch # These patches are only for the testsuite: #900_testsuite_groupmems #901_testsuite_gcov |