[kernel] r15652 - in dists/lenny-security/linux-2.6/debian: . patches/bugfix/all patches/bugfix/powerpc patches/series
Dann Frazier
dannf at alioth.debian.org
Mon May 10 05:21:33 UTC 2010
Author: dannf
Date: Mon May 10 05:21:29 2010
New Revision: 15652
Log:
KEYS: find_keyring_by_name() can gain access to a freed keyring
(CVE-2010-1437)
Added:
dists/lenny-security/linux-2.6/debian/patches/bugfix/all/keys-find_keyring_by_name-can-gain-access-to-a-freed-keyring.patch
dists/lenny-security/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch
- copied unchanged from r15639, dists/sid/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch
Modified:
dists/lenny-security/linux-2.6/debian/changelog
dists/lenny-security/linux-2.6/debian/patches/series/22lenny1
Modified: dists/lenny-security/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny-security/linux-2.6/debian/changelog Sun May 9 16:50:27 2010 (r15651)
+++ dists/lenny-security/linux-2.6/debian/changelog Mon May 10 05:21:29 2010 (r15652)
@@ -13,6 +13,8 @@
* sctp: Fix skb_over_panic resulting from multiple invalid parameter
errors (CVE-2010-1173)
* sparc64: Fix sun4u execute bit check in TSB I-TLB load (CVE-2010-1451)
+ * KEYS: find_keyring_by_name() can gain access to a freed keyring
+ (CVE-2010-1437)
[ Ben Hutchings ]
* [x86] KVM: disable paravirt mmu reporting (Closes: #573071) (regressed
Added: dists/lenny-security/linux-2.6/debian/patches/bugfix/all/keys-find_keyring_by_name-can-gain-access-to-a-freed-keyring.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/all/keys-find_keyring_by_name-can-gain-access-to-a-freed-keyring.patch Mon May 10 05:21:29 2010 (r15652)
@@ -0,0 +1,183 @@
+commit 697efd52b4c5374c2133f5fe86a354f1b163a22d
+Author: Toshiyuki Okajima <toshi.okajima at jp.fujitsu.com>
+Date: Fri Apr 30 14:32:13 2010 +0100
+
+ KEYS: find_keyring_by_name() can gain access to a freed keyring
+
+ find_keyring_by_name() can gain access to a keyring that has had its reference
+ count reduced to zero, and is thus ready to be freed. This then allows the
+ dead keyring to be brought back into use whilst it is being destroyed.
+
+ The following timeline illustrates the process:
+
+ |(cleaner) (user)
+ |
+ | free_user(user) sys_keyctl()
+ | | |
+ | key_put(user->session_keyring) keyctl_get_keyring_ID()
+ | || //=> keyring->usage = 0 |
+ | |schedule_work(&key_cleanup_task) lookup_user_key()
+ | || |
+ | kmem_cache_free(,user) |
+ | . |[KEY_SPEC_USER_KEYRING]
+ | . install_user_keyrings()
+ | . ||
+ | key_cleanup() [<= worker_thread()] ||
+ | | ||
+ | [spin_lock(&key_serial_lock)] |[mutex_lock(&key_user_keyr..mutex)]
+ | | ||
+ | atomic_read() == 0 ||
+ | |{ rb_ease(&key->serial_node,) } ||
+ | | ||
+ | [spin_unlock(&key_serial_lock)] |find_keyring_by_name()
+ | | |||
+ | keyring_destroy(keyring) ||[read_lock(&keyring_name_lock)]
+ | || |||
+ | |[write_lock(&keyring_name_lock)] ||atomic_inc(&keyring->usage)
+ | |. ||| *** GET freeing keyring ***
+ | |. ||[read_unlock(&keyring_name_lock)]
+ | || ||
+ | |list_del() |[mutex_unlock(&key_user_k..mutex)]
+ | || |
+ | |[write_unlock(&keyring_name_lock)] ** INVALID keyring is returned **
+ | | .
+ | kmem_cache_free(,keyring) .
+ | .
+ | atomic_dec(&keyring->usage)
+ v *** DESTROYED ***
+ TIME
+
+ If CONFIG_SLUB_DEBUG=y then we may see the following message generated:
+
+ =============================================================================
+ BUG key_jar: Poison overwritten
+ -----------------------------------------------------------------------------
+
+ INFO: 0xffff880197a7e200-0xffff880197a7e200. First byte 0x6a instead of 0x6b
+ INFO: Allocated in key_alloc+0x10b/0x35f age=25 cpu=1 pid=5086
+ INFO: Freed in key_cleanup+0xd0/0xd5 age=12 cpu=1 pid=10
+ INFO: Slab 0xffffea000592cb90 objects=16 used=2 fp=0xffff880197a7e200 flags=0x200000000000c3
+ INFO: Object 0xffff880197a7e200 @offset=512 fp=0xffff880197a7e300
+
+ Bytes b4 0xffff880197a7e1f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ
+ Object 0xffff880197a7e200: 6a 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b jkkkkkkkkkkkkkkk
+
+ Alternatively, we may see a system panic happen, such as:
+
+ BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
+ IP: [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
+ PGD 6b2b4067 PUD 6a80d067 PMD 0
+ Oops: 0000 [#1] SMP
+ last sysfs file: /sys/kernel/kexec_crash_loaded
+ CPU 1
+ ...
+ Pid: 31245, comm: su Not tainted 2.6.34-rc5-nofixed-nodebug #2 D2089/PRIMERGY
+ RIP: 0010:[<ffffffff810e61a3>] [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
+ RSP: 0018:ffff88006af3bd98 EFLAGS: 00010002
+ RAX: 0000000000000000 RBX: 0000000000000001 RCX: ffff88007d19900b
+ RDX: 0000000100000000 RSI: 00000000000080d0 RDI: ffffffff81828430
+ RBP: ffffffff81828430 R08: ffff88000a293750 R09: 0000000000000000
+ R10: 0000000000000001 R11: 0000000000100000 R12: 00000000000080d0
+ R13: 00000000000080d0 R14: 0000000000000296 R15: ffffffff810f20ce
+ FS: 00007f97116bc700(0000) GS:ffff88000a280000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000000000001 CR3: 000000006a91c000 CR4: 00000000000006e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+ Process su (pid: 31245, threadinfo ffff88006af3a000, task ffff8800374414c0)
+ Stack:
+ 0000000512e0958e 0000000000008000 ffff880037f8d180 0000000000000001
+ 0000000000000000 0000000000008001 ffff88007d199000 ffffffff810f20ce
+ 0000000000008000 ffff88006af3be48 0000000000000024 ffffffff810face3
+ Call Trace:
+ [<ffffffff810f20ce>] ? get_empty_filp+0x70/0x12f
+ [<ffffffff810face3>] ? do_filp_open+0x145/0x590
+ [<ffffffff810ce208>] ? tlb_finish_mmu+0x2a/0x33
+ [<ffffffff810ce43c>] ? unmap_region+0xd3/0xe2
+ [<ffffffff810e4393>] ? virt_to_head_page+0x9/0x2d
+ [<ffffffff81103916>] ? alloc_fd+0x69/0x10e
+ [<ffffffff810ef4ed>] ? do_sys_open+0x56/0xfc
+ [<ffffffff81008a02>] ? system_call_fastpath+0x16/0x1b
+ Code: 0f 1f 44 00 00 49 89 c6 fa 66 0f 1f 44 00 00 65 4c 8b 04 25 60 e8 00 00 48 8b 45 00 49 01 c0 49 8b 18 48 85 db 74 0d 48 63 45 18 <48> 8b 04 03 49 89 00 eb 14 4c 89 f9 83 ca ff 44 89 e6 48 89 ef
+ RIP [<ffffffff810e61a3>] kmem_cache_alloc+0x5b/0xe9
+
+ This problem is that find_keyring_by_name does not confirm that the keyring is
+ valid before accepting it.
+
+ Skipping keyrings that have been reduced to a zero count seems the way to go.
+ To this end, use atomic_inc_not_zero() to increment the usage count and skip
+ the candidate keyring if that returns false.
+
+ The following script _may_ cause the bug to happen, but there's no guarantee
+ as the window of opportunity is small:
+
+ #!/bin/sh
+ LOOP=100000
+ USER=dummy_user
+ /bin/su -c "exit;" $USER || { /usr/sbin/adduser -m $USER; add=1; }
+ for ((i=0; i<LOOP; i++))
+ do
+ /bin/su -c "echo '$i' > /dev/null" $USER
+ done
+ (( add == 1 )) && /usr/sbin/userdel -r $USER
+ exit
+
+ Note that the nominated user must not be in use.
+
+ An alternative way of testing this may be:
+
+ for ((i=0; i<100000; i++))
+ do
+ keyctl session foo /bin/true || break
+ done >&/dev/null
+
+ as that uses a keyring named "foo" rather than relying on the user and
+ user-session named keyrings.
+
+ Reported-by: Toshiyuki Okajima <toshi.okajima at jp.fujitsu.com>
+ Signed-off-by: David Howells <dhowells at redhat.com>
+ Tested-by: Toshiyuki Okajima <toshi.okajima at jp.fujitsu.com>
+ Acked-by: Serge Hallyn <serue at us.ibm.com>
+ Signed-off-by: James Morris <jmorris at namei.org>
+
+diff --git a/security/keys/keyring.c b/security/keys/keyring.c
+index a9ab8af..594660f 100644
+--- a/security/keys/keyring.c
++++ b/security/keys/keyring.c
+@@ -523,9 +523,8 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
+ struct key *keyring;
+ int bucket;
+
+- keyring = ERR_PTR(-EINVAL);
+ if (!name)
+- goto error;
++ return ERR_PTR(-EINVAL);
+
+ bucket = keyring_hash(name);
+
+@@ -549,17 +548,18 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
+ KEY_SEARCH) < 0)
+ continue;
+
+- /* we've got a match */
+- atomic_inc(&keyring->usage);
+- read_unlock(&keyring_name_lock);
+- goto error;
++ /* we've got a match but we might end up racing with
++ * key_cleanup() if the keyring is currently 'dead'
++ * (ie. it has a zero usage count) */
++ if (!atomic_inc_not_zero(&keyring->usage))
++ continue;
++ goto out;
+ }
+ }
+
+- read_unlock(&keyring_name_lock);
+ keyring = ERR_PTR(-ENOKEY);
+-
+- error:
++out:
++ read_unlock(&keyring_name_lock);
+ return keyring;
+
+ } /* end find_keyring_by_name() */
Copied: dists/lenny-security/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch (from r15639, dists/sid/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/lenny-security/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch Mon May 10 05:21:29 2010 (r15652, copy of r15639, dists/sid/linux-2.6/debian/patches/bugfix/powerpc/kgdb-dont-needlessly-skip-PAGE_USER-test-for-Fsl-booke.patch)
@@ -0,0 +1,42 @@
+commit 56151e753468e34aeb322af4b0309ab727c97d2e
+Author: Wufei <fei.wu at windriver.com>
+Date: Wed Apr 28 17:42:32 2010 -0400
+
+ kgdb: don't needlessly skip PAGE_USER test for Fsl booke
+
+ The bypassing of this test is a leftover from 2.4 vintage
+ kernels, and is no longer appropriate, or even used by KGDB.
+ Currently KGDB uses probe_kernel_write() for all access to
+ memory via the KGDB core, so it can simply be deleted.
+
+ This fixes CVE-2010-1446.
+
+ CC: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+ CC: Paul Mackerras <paulus at samba.org>
+ CC: Kumar Gala <galak at kernel.crashing.org>
+ Signed-off-by: Wufei <fei.wu at windriver.com>
+ Signed-off-by: Jason Wessel <jason.wessel at windriver.com>
+
+
+Adjusted to apply to Debian's 2.6.32 by dann frazier <dannf at debian.org>
+
+
+diff -urpN a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
+--- a/arch/powerpc/mm/fsl_booke_mmu.c 2009-12-02 20:51:21.000000000 -0700
++++ b/arch/powerpc/mm/fsl_booke_mmu.c 2010-04-30 00:49:04.000000000 -0600
+@@ -131,15 +131,10 @@ void settlbcam(int index, unsigned long
+ TLBCAM[index].MAS3 = (phys & PAGE_MASK) | MAS3_SX | MAS3_SR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
+
+-#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER) {
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+ }
+-#else
+- TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+- TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+-#endif
+
+ tlbcam_addrs[index].start = virt;
+ tlbcam_addrs[index].limit = virt + size - 1;
Modified: dists/lenny-security/linux-2.6/debian/patches/series/22lenny1
==============================================================================
--- dists/lenny-security/linux-2.6/debian/patches/series/22lenny1 Sun May 9 16:50:27 2010 (r15651)
+++ dists/lenny-security/linux-2.6/debian/patches/series/22lenny1 Mon May 10 05:21:29 2010 (r15652)
@@ -12,3 +12,4 @@
+ bugfix/all/tipc-fix-oops-on-send-prior-to-entering-networked-mode.patch
+ bugfix/all/sctp-fix-skb_over_panic-resulting-from-multiple-invalid-parameter-errors.patch
+ bugfix/sparc/fix-sun4u-execute-bit-check-in-TSB-I-ITLB-load.patch
++ bugfix/all/keys-find_keyring_by_name-can-gain-access-to-a-freed-keyring.patch
More information about the Kernel-svn-changes
mailing list