| From 4d4ea8b53f6dae1fb354b8536a0ead210d6ea6d4 Mon Sep 17 00:00:00 2001 |
| From: David Howells <dhowells@redhat.com> |
| Date: Fri, 27 Aug 2010 14:04:07 +0200 |
| Subject: [PATCH] KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring |
| |
| commit 4d4ea8b53f6dae1fb354b8536a0ead210d6ea6d4 in tip. |
| |
| commit 3d96406c7da1ed5811ea52a3b0905f4f0e295376 upstream |
| |
| Fix a bug in keyctl_session_to_parent() whereby it tries to check the ownership |
| of the parent process's session keyring whether or not the parent has a session |
| keyring [CVE-2010-2960]. |
| |
| A program like the following: |
| |
| #include <unistd.h> |
| #include <keyutils.h> |
| int main(int argc, char **argv) |
| { |
| keyctl(KEYCTL_SESSION_TO_PARENT); |
| } |
| |
| can be used to trigger the following bug report: |
| |
| BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0 |
| IP: [<ffffffff811ae4dd>] keyctl_session_to_parent+0x251/0x443 |
| ... |
| Call Trace: |
| [<ffffffff811ae2f3>] ? keyctl_session_to_parent+0x67/0x443 |
| [<ffffffff8109d286>] ? __do_fault+0x24b/0x3d0 |
| [<ffffffff811af98c>] sys_keyctl+0xb4/0xb8 |
| [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b |
| |
| if there is no parent process. |
| |
| If the system is using pam_keyinit then it mostly protected against this as all |
| processes derived from a login will have inherited the session keyring created |
| by pam_keyinit during the log in procedure. |
| |
| To test this, pam_keyinit calls need to be commented out in /etc/pam.d/. |
| |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: John Kacur <jkacur@redhat.com> |
| |
| diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c |
| index d29e022..c25603a 100644 |
| --- a/security/keys/keyctl.c |
| +++ b/security/keys/keyctl.c |
| @@ -1292,7 +1292,8 @@ long keyctl_session_to_parent(void) |
| goto not_permitted; |
| |
| /* the keyrings must have the same UID */ |
| - if (pcred ->tgcred->session_keyring->uid != mycred->euid || |
| + if ((pcred->tgcred->session_keyring && |
| + pcred->tgcred->session_keyring->uid != mycred->euid) || |
| mycred->tgcred->session_keyring->uid != mycred->euid) |
| goto not_permitted; |
| |
| -- |
| 1.7.1.1 |
| |