[kernel] r16690 - in dists/sid/linux-2.6/debian: . patches/bugfix/all patches/series
Ben Hutchings
benh at alioth.debian.org
Fri Dec 10 04:17:20 UTC 2010
Author: benh
Date: Fri Dec 10 04:17:15 2010
New Revision: 16690
Log:
Add 2 security patches already queued for lenny-security
Added:
dists/sid/linux-2.6/debian/patches/bugfix/all/filter-make-sure-filters-dont-read-uninitialized-mem.patch
dists/sid/linux-2.6/debian/patches/bugfix/all/posix-cpu-timers-workaround-to-suppress-the-problems-with-mt-exec.patch
Modified:
dists/sid/linux-2.6/debian/changelog
dists/sid/linux-2.6/debian/patches/series/29
Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog Fri Dec 10 03:19:38 2010 (r16689)
+++ dists/sid/linux-2.6/debian/changelog Fri Dec 10 04:17:15 2010 (r16690)
@@ -59,6 +59,9 @@
- ivtvfb: prevent reading uninitialized stack memory (CVE-2010-4079)
- net/sched: fix some kernel information leaks
* TTY: Fix error return from tty_ldisc_open() (regression in 2.6.32.27)
+ * filter: make sure filters dont read uninitialized memory (CVE-2010-4158)
+ * posix-cpu-timers: workaround to suppress the problems with mt exec
+ (CVE-2010-4248)
[ Ian Campbell ]
* xen: disable ACPI NUMA for PV guests and allow IRQ desc allocation on any
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/filter-make-sure-filters-dont-read-uninitialized-mem.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/filter-make-sure-filters-dont-read-uninitialized-mem.patch Fri Dec 10 04:17:15 2010 (r16690)
@@ -0,0 +1,231 @@
+From: David S. Miller <davem at davemloft.net>
+Date: Wed, 10 Nov 2010 10:38:24 -0800
+Subject: [PATCH] filter: make sure filters dont read uninitialized memory
+
+commit 57fe93b374a6b8711995c2d466c502af9f3a08bb upstream.
+
+There is a possibility malicious users can get limited information about
+uninitialized stack mem array. Even if sk_run_filter() result is bound
+to packet length (0 .. 65535), we could imagine this can be used by
+hostile user.
+
+Initializing mem[] array, like Dan Rosenberg suggested in his patch is
+expensive since most filters dont even use this array.
+
+Its hard to make the filter validation in sk_chk_filter(), because of
+the jumps. This might be done later.
+
+In this patch, I use a bitmap (a single long var) so that only filters
+using mem[] loads/stores pay the price of added security checks.
+
+For other filters, additional cost is a single instruction.
+
+[ Since we access fentry->k a lot now, cache it in a local variable
+ and mark filter entry pointer as const. -DaveM ]
+
+Reported-by: Dan Rosenberg <drosenberg at vsecurity.com>
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[Backported by dann frazier <dannf at debian.org>]
+---
+diff --git a/net/core/filter.c b/net/core/filter.c
+index df37443..506a7d1 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -111,39 +111,41 @@ EXPORT_SYMBOL(sk_filter);
+ */
+ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
+ {
+- struct sock_filter *fentry; /* We walk down these */
+ void *ptr;
+ u32 A = 0; /* Accumulator */
+ u32 X = 0; /* Index Register */
+ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
++ unsigned long memvalid = 0;
+ u32 tmp;
+ int k;
+ int pc;
+
++ BUILD_BUG_ON(BPF_MEMWORDS > BITS_PER_LONG);
+ /*
+ * Process array of filter instructions.
+ */
+ for (pc = 0; pc < flen; pc++) {
+- fentry = &filter[pc];
++ const struct sock_filter *fentry = &filter[pc];
++ u32 f_k = fentry->k;
+
+ switch (fentry->code) {
+ case BPF_ALU|BPF_ADD|BPF_X:
+ A += X;
+ continue;
+ case BPF_ALU|BPF_ADD|BPF_K:
+- A += fentry->k;
++ A += f_k;
+ continue;
+ case BPF_ALU|BPF_SUB|BPF_X:
+ A -= X;
+ continue;
+ case BPF_ALU|BPF_SUB|BPF_K:
+- A -= fentry->k;
++ A -= f_k;
+ continue;
+ case BPF_ALU|BPF_MUL|BPF_X:
+ A *= X;
+ continue;
+ case BPF_ALU|BPF_MUL|BPF_K:
+- A *= fentry->k;
++ A *= f_k;
+ continue;
+ case BPF_ALU|BPF_DIV|BPF_X:
+ if (X == 0)
+@@ -151,49 +153,49 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
+ A /= X;
+ continue;
+ case BPF_ALU|BPF_DIV|BPF_K:
+- A /= fentry->k;
++ A /= f_k;
+ continue;
+ case BPF_ALU|BPF_AND|BPF_X:
+ A &= X;
+ continue;
+ case BPF_ALU|BPF_AND|BPF_K:
+- A &= fentry->k;
++ A &= f_k;
+ continue;
+ case BPF_ALU|BPF_OR|BPF_X:
+ A |= X;
+ continue;
+ case BPF_ALU|BPF_OR|BPF_K:
+- A |= fentry->k;
++ A |= f_k;
+ continue;
+ case BPF_ALU|BPF_LSH|BPF_X:
+ A <<= X;
+ continue;
+ case BPF_ALU|BPF_LSH|BPF_K:
+- A <<= fentry->k;
++ A <<= f_k;
+ continue;
+ case BPF_ALU|BPF_RSH|BPF_X:
+ A >>= X;
+ continue;
+ case BPF_ALU|BPF_RSH|BPF_K:
+- A >>= fentry->k;
++ A >>= f_k;
+ continue;
+ case BPF_ALU|BPF_NEG:
+ A = -A;
+ continue;
+ case BPF_JMP|BPF_JA:
+- pc += fentry->k;
++ pc += f_k;
+ continue;
+ case BPF_JMP|BPF_JGT|BPF_K:
+- pc += (A > fentry->k) ? fentry->jt : fentry->jf;
++ pc += (A > f_k) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_JMP|BPF_JGE|BPF_K:
+- pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
++ pc += (A >= f_k) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_JMP|BPF_JEQ|BPF_K:
+- pc += (A == fentry->k) ? fentry->jt : fentry->jf;
++ pc += (A == f_k) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_JMP|BPF_JSET|BPF_K:
+- pc += (A & fentry->k) ? fentry->jt : fentry->jf;
++ pc += (A & f_k) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_JMP|BPF_JGT|BPF_X:
+ pc += (A > X) ? fentry->jt : fentry->jf;
+@@ -208,7 +210,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
+ pc += (A & X) ? fentry->jt : fentry->jf;
+ continue;
+ case BPF_LD|BPF_W|BPF_ABS:
+- k = fentry->k;
++ k = f_k;
+ load_w:
+ ptr = load_pointer(skb, k, 4, &tmp);
+ if (ptr != NULL) {
+@@ -217,7 +219,7 @@ load_w:
+ }
+ break;
+ case BPF_LD|BPF_H|BPF_ABS:
+- k = fentry->k;
++ k = f_k;
+ load_h:
+ ptr = load_pointer(skb, k, 2, &tmp);
+ if (ptr != NULL) {
+@@ -226,7 +228,7 @@ load_h:
+ }
+ break;
+ case BPF_LD|BPF_B|BPF_ABS:
+- k = fentry->k;
++ k = f_k;
+ load_b:
+ ptr = load_pointer(skb, k, 1, &tmp);
+ if (ptr != NULL) {
+@@ -241,32 +243,34 @@ load_b:
+ X = skb->len;
+ continue;
+ case BPF_LD|BPF_W|BPF_IND:
+- k = X + fentry->k;
++ k = X + f_k;
+ goto load_w;
+ case BPF_LD|BPF_H|BPF_IND:
+- k = X + fentry->k;
++ k = X + f_k;
+ goto load_h;
+ case BPF_LD|BPF_B|BPF_IND:
+- k = X + fentry->k;
++ k = X + f_k;
+ goto load_b;
+ case BPF_LDX|BPF_B|BPF_MSH:
+- ptr = load_pointer(skb, fentry->k, 1, &tmp);
++ ptr = load_pointer(skb, f_k, 1, &tmp);
+ if (ptr != NULL) {
+ X = (*(u8 *)ptr & 0xf) << 2;
+ continue;
+ }
+ return 0;
+ case BPF_LD|BPF_IMM:
+- A = fentry->k;
++ A = f_k;
+ continue;
+ case BPF_LDX|BPF_IMM:
+- X = fentry->k;
++ X = f_k;
+ continue;
+ case BPF_LD|BPF_MEM:
+- A = mem[fentry->k];
++ A = (memvalid & (1UL << f_k)) ?
++ mem[f_k] : 0;
+ continue;
+ case BPF_LDX|BPF_MEM:
+- X = mem[fentry->k];
++ X = (memvalid & (1UL << f_k)) ?
++ mem[f_k] : 0;
+ continue;
+ case BPF_MISC|BPF_TAX:
+ X = A;
+@@ -275,14 +279,16 @@ load_b:
+ A = X;
+ continue;
+ case BPF_RET|BPF_K:
+- return fentry->k;
++ return f_k;
+ case BPF_RET|BPF_A:
+ return A;
+ case BPF_ST:
+- mem[fentry->k] = A;
++ memvalid |= 1UL << f_k;
++ mem[f_k] = A;
+ continue;
+ case BPF_STX:
+- mem[fentry->k] = X;
++ memvalid |= 1UL << f_k;
++ mem[f_k] = X;
+ continue;
+ default:
+ WARN_ON(1);
Added: dists/sid/linux-2.6/debian/patches/bugfix/all/posix-cpu-timers-workaround-to-suppress-the-problems-with-mt-exec.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/posix-cpu-timers-workaround-to-suppress-the-problems-with-mt-exec.patch Fri Dec 10 04:17:15 2010 (r16690)
@@ -0,0 +1,59 @@
+From: Oleg Nesterov <oleg at redhat.com>
+Date: Fri, 5 Nov 2010 16:53:42 +0100
+Subject: [PATCH] posix-cpu-timers: workaround to suppress the problems with mt exec
+
+commit e0a70217107e6f9844628120412cb27bb4cea194 upstream.
+
+posix-cpu-timers.c correctly assumes that the dying process does
+posix_cpu_timers_exit_group() and removes all !CPUCLOCK_PERTHREAD
+timers from signal->cpu_timers list.
+
+But, it also assumes that timer->it.cpu.task is always the group
+leader, and thus the dead ->task means the dead thread group.
+
+This is obviously not true after de_thread() changes the leader.
+After that almost every posix_cpu_timer_ method has problems.
+
+It is not simple to fix this bug correctly. First of all, I think
+that timer->it.cpu should use struct pid instead of task_struct.
+Also, the locking should be reworked completely. In particular,
+tasklist_lock should not be used at all. This all needs a lot of
+nontrivial and hard-to-test changes.
+
+Change __exit_signal() to do posix_cpu_timers_exit_group() when
+the old leader dies during exec. This is not the fix, just the
+temporary hack to hide the problem for 2.6.37 and stable. IOW,
+this is obviously wrong but this is what we currently have anyway:
+cpu timers do not work after mt exec.
+
+In theory this change adds another race. The exiting leader can
+detach the timers which were attached to the new leader. However,
+the window between de_thread() and release_task() is small, we
+can pretend that sys_timer_create() was called before de_thread().
+
+Signed-off-by: Oleg Nesterov <oleg at redhat.com>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+[Backported by dann frazier <dannf at debian.org>]
+---
+ kernel/exit.c | 8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/kernel/exit.c b/kernel/exit.c
+index 2bd672d..b3b6377 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -93,6 +93,14 @@ static void __exit_signal(struct task_struct *tsk)
+ posix_cpu_timers_exit_group(tsk);
+ else {
+ /*
++ * This can only happen if the caller is de_thread().
++ * FIXME: this is the temporary hack, we should teach
++ * posix-cpu-timers to handle this case correctly.
++ */
++ if (unlikely(has_group_leader_pid(tsk)))
++ posix_cpu_timers_exit_group(tsk);
++
++ /*
+ * If there is any task waiting for the group exit
+ * then notify it:
+ */
Modified: dists/sid/linux-2.6/debian/patches/series/29
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/29 Fri Dec 10 03:19:38 2010 (r16689)
+++ dists/sid/linux-2.6/debian/patches/series/29 Fri Dec 10 04:17:15 2010 (r16690)
@@ -37,3 +37,5 @@
+ bugfix/all/stable/2.6.32.27.patch
+ debian/block-Avoid-ABI-change-from-fix-to-blk_queue_physica.patch
+ bugfix/all/TTY-Fix-error-return-from-tty_ldisc_open.patch
++ bugfix/all/filter-make-sure-filters-dont-read-uninitialized-mem.patch
++ bugfix/all/posix-cpu-timers-workaround-to-suppress-the-problems-with-mt-exec.patch
More information about the Kernel-svn-changes
mailing list