summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2012-11-11 20:46:20 -0500
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-11-11 20:46:20 -0500
commitde8314e6bce3a00cba4b524d9ee71d526fada7a1 (patch)
tree91336acb311ccaadab7b1c111840806b30f0a2b0
parent501871719a80080804d8d635c8d1efc469b4c282 (diff)
downloadlongterm-queue-2.6.34-de8314e6bce3a00cba4b524d9ee71d526fada7a1.tar.gz
add a couple CVE like fixes
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/genalloc-stop-crashing-the-system-when-destroying-a-.patch132
-rw-r--r--queue/inotify-stop-kernel-memory-leak-on-file-creation-fai.patch33
-rw-r--r--queue/series2
3 files changed, 167 insertions, 0 deletions
diff --git a/queue/genalloc-stop-crashing-the-system-when-destroying-a-.patch b/queue/genalloc-stop-crashing-the-system-when-destroying-a-.patch
new file mode 100644
index 0000000..a9f9d6c
--- /dev/null
+++ b/queue/genalloc-stop-crashing-the-system-when-destroying-a-.patch
@@ -0,0 +1,132 @@
+From 1509309d1a9fde19371131b7131966626ff84d7c Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Date: Thu, 25 Oct 2012 13:37:51 -0700
+Subject: [PATCH] genalloc: stop crashing the system when destroying a pool
+
+commit eedce141cd2dad8d0cefc5468ef41898949a7031 upstream.
+
+The genalloc code uses the bitmap API from include/linux/bitmap.h and
+lib/bitmap.c, which is based on long values. Both bitmap_set from
+lib/bitmap.c and bitmap_set_ll, which is the lockless version from
+genalloc.c, use BITMAP_LAST_WORD_MASK to set the first bits in a long in
+the bitmap.
+
+That one uses (1 << bits) - 1, 0b111, if you are setting the first three
+bits. This means that the API counts from the least significant bits
+(LSB from now on) to the MSB. The LSB in the first long is bit 0, then.
+The same works for the lookup functions.
+
+The genalloc code uses longs for the bitmap, as it should. In
+include/linux/genalloc.h, struct gen_pool_chunk has unsigned long
+bits[0] as its last member. When allocating the struct, genalloc should
+reserve enough space for the bitmap. This should be a proper number of
+longs that can fit the amount of bits in the bitmap.
+
+However, genalloc allocates an integer number of bytes that fit the
+amount of bits, but may not be an integer amount of longs. 9 bytes, for
+example, could be allocated for 70 bits.
+
+This is a problem in itself if the Least Significat Bit in a long is in
+the byte with the largest address, which happens in Big Endian machines.
+This means genalloc is not allocating the byte in which it will try to
+set or check for a bit.
+
+This may end up in memory corruption, where genalloc will try to set the
+bits it has not allocated. In fact, genalloc may not set these bits
+because it may find them already set, because they were not zeroed since
+they were not allocated. And that's what causes a BUG when
+gen_pool_destroy is called and check for any set bits.
+
+What really happens is that genalloc uses kmalloc_node with __GFP_ZERO
+on gen_pool_add_virt. With SLAB and SLUB, this means the whole slab
+will be cleared, not only the requested bytes. Since struct
+gen_pool_chunk has a size that is a multiple of 8, and slab sizes are
+multiples of 8, we get lucky and allocate and clear the right amount of
+bytes.
+
+Hower, this is not the case with SLOB or with older code that did memset
+after allocating instead of using __GFP_ZERO.
+
+So, a simple module as this (running 3.6.0), will cause a crash when
+rmmod'ed.
+
+ [root@phantom-lp2 foo]# cat foo.c
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/genalloc.h>
+
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION("0.1");
+
+ static struct gen_pool *foo_pool;
+
+ static __init int foo_init(void)
+ {
+ int ret;
+ foo_pool = gen_pool_create(10, -1);
+ if (!foo_pool)
+ return -ENOMEM;
+ ret = gen_pool_add(foo_pool, 0xa0000000, 32 << 10, -1);
+ if (ret) {
+ gen_pool_destroy(foo_pool);
+ return ret;
+ }
+ return 0;
+ }
+
+ static __exit void foo_exit(void)
+ {
+ gen_pool_destroy(foo_pool);
+ }
+
+ module_init(foo_init);
+ module_exit(foo_exit);
+ [root@phantom-lp2 foo]# zcat /proc/config.gz | grep SLOB
+ CONFIG_SLOB=y
+ [root@phantom-lp2 foo]# insmod ./foo.ko
+ [root@phantom-lp2 foo]# rmmod foo
+ ------------[ cut here ]------------
+ kernel BUG at lib/genalloc.c:243!
+ cpu 0x4: Vector: 700 (Program Check) at [c0000000bb0e7960]
+ pc: c0000000003cb50c: .gen_pool_destroy+0xac/0x110
+ lr: c0000000003cb4fc: .gen_pool_destroy+0x9c/0x110
+ sp: c0000000bb0e7be0
+ msr: 8000000000029032
+ current = 0xc0000000bb0e0000
+ paca = 0xc000000006d30e00 softe: 0 irq_happened: 0x01
+ pid = 13044, comm = rmmod
+ kernel BUG at lib/genalloc.c:243!
+ [c0000000bb0e7ca0] d000000004b00020 .foo_exit+0x20/0x38 [foo]
+ [c0000000bb0e7d20] c0000000000dff98 .SyS_delete_module+0x1a8/0x290
+ [c0000000bb0e7e30] c0000000000097d4 syscall_exit+0x0/0x94
+ --- Exception: c00 (System Call) at 000000800753d1a0
+ SP (fffd0b0e640) is in userspace
+
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
+Cc: Benjamin Gaignard <benjamin.gaignard@stericsson.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ lib/genalloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/genalloc.c b/lib/genalloc.c
+index 736c3b0..3c76249 100644
+--- a/lib/genalloc.c
++++ b/lib/genalloc.c
+@@ -54,7 +54,7 @@ int gen_pool_add(struct gen_pool *pool, unsigned long addr, size_t size,
+ struct gen_pool_chunk *chunk;
+ int nbits = size >> pool->min_alloc_order;
+ int nbytes = sizeof(struct gen_pool_chunk) +
+- (nbits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
++ BITS_TO_LONGS(nbits) * sizeof(long);
+
+ chunk = kmalloc_node(nbytes, GFP_KERNEL | __GFP_ZERO, nid);
+ if (unlikely(chunk == NULL))
+--
+1.7.12.1
+
diff --git a/queue/inotify-stop-kernel-memory-leak-on-file-creation-fai.patch b/queue/inotify-stop-kernel-memory-leak-on-file-creation-fai.patch
new file mode 100644
index 0000000..4dcda06
--- /dev/null
+++ b/queue/inotify-stop-kernel-memory-leak-on-file-creation-fai.patch
@@ -0,0 +1,33 @@
+From aa0923d85d7a9cc59fd4e5ea8555e045d8dacaa7 Mon Sep 17 00:00:00 2001
+From: Eric Paris <eparis@redhat.com>
+Date: Tue, 23 Nov 2010 18:18:37 -0500
+Subject: [PATCH] inotify: stop kernel memory leak on file creation failure
+
+commit a2ae4cc9a16e211c8a128ba10d22a85431f093ab upstream.
+
+If inotify_init is unable to allocate a new file for the new inotify
+group we leak the new group. This patch drops the reference on the
+group on file allocation failure.
+
+Reported-by: Vegard Nossum <vegard.nossum@gmail.com>
+Signed-off-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+---
+ fs/notify/inotify/inotify_user.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
+index 0c6bbc0..72f8825 100644
+--- a/fs/notify/inotify/inotify_user.c
++++ b/fs/notify/inotify/inotify_user.c
+@@ -674,6 +674,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
+ if (ret >= 0)
+ return ret;
+
++ fsnotify_put_group(group);
+ atomic_dec(&user->inotify_devs);
+ out_free_uid:
+ free_uid(user);
+--
+1.7.12.1
+
diff --git a/queue/series b/queue/series
index 587c099..b5d97d9 100644
--- a/queue/series
+++ b/queue/series
@@ -12,6 +12,8 @@ cifs-fix-cifs-stable-patch-cifs-fix-oplock-break-han.patch
gro-reset-vlan_tci-on-reuse.patch
md-Fix-handling-for-devices-from-2TB-to-4TB-in-0.90-.patch
md-Don-t-truncate-size-at-4TB-for-RAID0-and-Linear.patch
+genalloc-stop-crashing-the-system-when-destroying-a-.patch
+inotify-stop-kernel-memory-leak-on-file-creation-fai.patch
# from .50
i2c-algo-bit-Generate-correct-i2c-address-sequence-f.patch