diff options
author | Leo Famulari <leo@famulari.name> | 2017-02-23 14:35:00 -0500 |
---|---|---|
committer | Leo Famulari <leo@famulari.name> | 2017-02-23 14:59:50 -0500 |
commit | 1c851cbe0c562894bd38c0f9f39d12be306b3e59 (patch) | |
tree | fe777346a55ad452b1c90d5859468df0cba06c53 /gnu | |
parent | 9f05908fb1e3707cae593d94688748294717a546 (diff) | |
download | guix-1c851cbe0c562894bd38c0f9f39d12be306b3e59.tar.gz |
gnu: shadow: Fix CVE-2017-2616.
* gnu/packages/patches/shadow-CVE-2017-2616.patch: New file. * gnu/local.mk (dist_patch_DATA): Add it. * gnu/packages/admin.scm (shadow): Use it.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/local.mk | 1 | ||||
-rw-r--r-- | gnu/packages/admin.scm | 3 | ||||
-rw-r--r-- | gnu/packages/patches/shadow-CVE-2017-2616.patch | 72 |
3 files changed, 75 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index ca415ec48f..2954549759 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -901,6 +901,7 @@ dist_patch_DATA = \ %D%/packages/patches/serf-comment-style-fix.patch \ %D%/packages/patches/serf-deflate-buckets-test-fix.patch \ %D%/packages/patches/shadow-4.4-su-snprintf-fix.patch \ + %D%/packages/patches/shadow-CVE-2017-2616.patch \ %D%/packages/patches/slim-session.patch \ %D%/packages/patches/slim-config.patch \ %D%/packages/patches/slim-sigusr1.patch \ diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm index b2207a1205..d9c7ba3b73 100644 --- a/gnu/packages/admin.scm +++ b/gnu/packages/admin.scm @@ -276,7 +276,8 @@ client and server, a telnet client and server, and an rsh client and server.") (uri (string-append "https://github.com/shadow-maint/shadow/releases/" "download/" version "/shadow-" version ".tar.xz")) - (patches (search-patches "shadow-4.4-su-snprintf-fix.patch")) + (patches (search-patches "shadow-4.4-su-snprintf-fix.patch" + "shadow-CVE-2017-2616.patch")) (sha256 (base32 "0g7hf55ar2pafg5g3ldx0fwzjk36wf4xb21p4ndanbjm3c2a9ab1")))) diff --git a/gnu/packages/patches/shadow-CVE-2017-2616.patch b/gnu/packages/patches/shadow-CVE-2017-2616.patch new file mode 100644 index 0000000000..f88aac40bc --- /dev/null +++ b/gnu/packages/patches/shadow-CVE-2017-2616.patch @@ -0,0 +1,72 @@ +Fix CVE-2017-2616: + +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-2616 +http://seclists.org/oss-sec/2017/q1/490 +http://seclists.org/oss-sec/2017/q1/474 + +Patch copied from upstream source repository: + +https://github.com/shadow-maint/shadow/commit/08fd4b69e84364677a10e519ccb25b71710ee686 + +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(-) + +diff --git a/src/su.c b/src/su.c +index f20d230..d86aa86 100644 +--- a/src/su.c ++++ b/src/su.c +@@ -379,11 +379,13 @@ static void prepare_pam_close_session (void) + /* 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); +@@ -393,9 +395,22 @@ static void prepare_pam_close_session (void) + snprintf (wait_msg, sizeof wait_msg, _(" ...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); + } + |