summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--trunk/2.6.18/00000_README14
-rw-r--r--trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch120
-rw-r--r--trunk/2.6.18/30064_RLIMIT_CPU-earlier-checking.patch80
-rw-r--r--trunk/2.6.18/30065_dnotify-race.patch22
4 files changed, 235 insertions, 1 deletions
diff --git a/trunk/2.6.18/00000_README b/trunk/2.6.18/00000_README
index 9202654..576a93b 100644
--- a/trunk/2.6.18/00000_README
+++ b/trunk/2.6.18/00000_README
@@ -285,7 +285,19 @@ Patches
be triggered by a user who already has additional priveleges (dialout
group). (closes: Debian #404815)
-
+30063_mmap-VM_DONTEXPAND.patch
+ [SECURITY] Add VM_DONTEXPAND to vm_flags in drivers that register
+ a fault handler but do not bounds check the offset argument
+ See CVE-2008-0007
+
+30064_RLIMIT_CPU-earlier-checking.patch
+ [SECURITY] Move check for an RLIMIT_CPU with a value of 0 earlier
+ to prevent a user escape (closes: #419706)
+ See CVE-2008-1294
+
+30065_dnotify-race.patch
+ [SECURITY] Fix a race in the directory notify
+ See CVE-2008-1375
50009_gentooify-tls-warning.patch
Change tls warning instructions to apply directly to Gentoo.
diff --git a/trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch b/trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch
new file mode 100644
index 0000000..9c285a2
--- /dev/null
+++ b/trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch
@@ -0,0 +1,120 @@
+From: Nick Piggin <npiggin@suse.de>
+Date: Sat, 2 Feb 2008 02:08:53 +0000 (+0100)
+Subject: vm audit: add VM_DONTEXPAND to mmap for drivers that need it (CVE-2008-0007)
+X-Git-Tag: v2.6.22.17~1
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fstable%2Flinux-2.6.22.y.git;a=commitdiff_plain;h=83af8eda68a3f0c227d0eb05348e58ae27a62e7e
+
+vm audit: add VM_DONTEXPAND to mmap for drivers that need it (CVE-2008-0007)
+
+Drivers that register a ->fault handler, but do not range-check the
+offset argument, must set VM_DONTEXPAND in the vm_flags in order to
+prevent an expanding mremap from overflowing the resource.
+
+I've audited the tree and attempted to fix these problems (usually by
+adding VM_DONTEXPAND where it is not obvious).
+
+Signed-off-by: Nick Piggin <npiggin@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+Backported to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/drivers/char/drm/drm_vm.c linux-source-2.6.18/drivers/char/drm/drm_vm.c
+--- linux-source-2.6.18.orig/drivers/char/drm/drm_vm.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/drivers/char/drm/drm_vm.c 2008-02-13 22:17:32.000000000 -0700
+@@ -479,6 +479,7 @@ static int drm_mmap_dma(struct file *fil
+ vma->vm_ops = &drm_vm_dma_ops;
+
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
++ vma->vm_flags |= VM_DONTEXPAND;
+
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open(vma);
+@@ -656,6 +657,7 @@ int drm_mmap(struct file *filp, struct v
+ return -EINVAL; /* This should never happen. */
+ }
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
++ vma->vm_flags |= VM_DONTEXPAND;
+
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open(vma);
+diff -urpN linux-source-2.6.18.orig/fs/ncpfs/mmap.c linux-source-2.6.18/fs/ncpfs/mmap.c
+--- linux-source-2.6.18.orig/fs/ncpfs/mmap.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/ncpfs/mmap.c 2008-02-13 22:17:35.000000000 -0700
+@@ -47,9 +47,6 @@ static struct page* ncp_file_mmap_nopage
+ pos = address - area->vm_start + (area->vm_pgoff << PAGE_SHIFT);
+
+ count = PAGE_SIZE;
+- if (address + PAGE_SIZE > area->vm_end) {
+- count = area->vm_end - address;
+- }
+ /* what we can read in one go */
+ bufsize = NCP_SERVER(inode)->buffer_size;
+
+diff -urpN linux-source-2.6.18.orig/kernel/relay.c linux-source-2.6.18/kernel/relay.c
+--- linux-source-2.6.18.orig/kernel/relay.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/kernel/relay.c 2008-02-13 22:17:35.000000000 -0700
+@@ -84,6 +84,7 @@ int relay_mmap_buf(struct rchan_buf *buf
+ return -EINVAL;
+
+ vma->vm_ops = &relay_file_mmap_ops;
++ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_private_data = buf;
+ buf->chan->cb->buf_mapped(buf, filp);
+
+diff -urpN linux-source-2.6.18.orig/sound/oss/via82cxxx_audio.c linux-source-2.6.18/sound/oss/via82cxxx_audio.c
+--- linux-source-2.6.18.orig/sound/oss/via82cxxx_audio.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/sound/oss/via82cxxx_audio.c 2008-02-13 22:17:35.000000000 -0700
+@@ -2104,6 +2104,7 @@ static struct page * via_mm_nopage (stru
+ {
+ struct via_info *card = vma->vm_private_data;
+ struct via_channel *chan = &card->ch_out;
++ unsigned long max_bufs;
+ struct page *dmapage;
+ unsigned long pgoff;
+ int rd, wr;
+@@ -2127,14 +2128,11 @@ static struct page * via_mm_nopage (stru
+ rd = card->ch_in.is_mapped;
+ wr = card->ch_out.is_mapped;
+
+-#ifndef VIA_NDEBUG
+- {
+- unsigned long max_bufs = chan->frag_number;
+- if (rd && wr) max_bufs *= 2;
+- /* via_dsp_mmap() should ensure this */
+- assert (pgoff < max_bufs);
+- }
+-#endif
++ max_bufs = chan->frag_number;
++ if (rd && wr)
++ max_bufs *= 2;
++ if (pgoff >= max_bufs)
++ return NOPAGE_SIGBUS;
+
+ /* if full-duplex (read+write) and we have two sets of bufs,
+ * then the playback buffers come first, sez soundcard.c */
+diff -urpN linux-source-2.6.18.orig/sound/usb/usx2y/usX2Yhwdep.c linux-source-2.6.18/sound/usb/usx2y/usX2Yhwdep.c
+--- linux-source-2.6.18.orig/sound/usb/usx2y/usX2Yhwdep.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/sound/usb/usx2y/usX2Yhwdep.c 2008-02-13 22:17:35.000000000 -0700
+@@ -88,7 +88,7 @@ static int snd_us428ctls_mmap(struct snd
+ us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
+ }
+ area->vm_ops = &us428ctls_vm_ops;
+- area->vm_flags |= VM_RESERVED;
++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_private_data = hw->private_data;
+ return 0;
+ }
+diff -urpN linux-source-2.6.18.orig/sound/usb/usx2y/usx2yhwdeppcm.c linux-source-2.6.18/sound/usb/usx2y/usx2yhwdeppcm.c
+--- linux-source-2.6.18.orig/sound/usb/usx2y/usx2yhwdeppcm.c 2008-02-10 10:48:45.000000000 -0700
++++ linux-source-2.6.18/sound/usb/usx2y/usx2yhwdeppcm.c 2008-02-13 22:17:35.000000000 -0700
+@@ -728,7 +728,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(stru
+ return -ENODEV;
+ }
+ area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
+- area->vm_flags |= VM_RESERVED;
++ area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+ area->vm_private_data = hw->private_data;
+ return 0;
+ }
diff --git a/trunk/2.6.18/30064_RLIMIT_CPU-earlier-checking.patch b/trunk/2.6.18/30064_RLIMIT_CPU-earlier-checking.patch
new file mode 100644
index 0000000..af498f1
--- /dev/null
+++ b/trunk/2.6.18/30064_RLIMIT_CPU-earlier-checking.patch
@@ -0,0 +1,80 @@
+commit 9926e4c74300c4b31dee007298c6475d33369df0
+Author: Tom Alsberg <alsbergt@cs.huji.ac.il>
+Date: Tue May 8 00:30:31 2007 -0700
+
+ CPU time limit patch / setrlimit(RLIMIT_CPU, 0) cheat fix
+
+ As discovered here today, the change in Kernel 2.6.17 intended to inhibit
+ users from setting RLIMIT_CPU to 0 (as that is equivalent to unlimited) by
+ "cheating" and setting it to 1 in such a case, does not make a difference,
+ as the check is done in the wrong place (too late), and only applies to the
+ profiling code.
+
+ On all systems I checked running kernels above 2.6.17, no matter what the
+ hard and soft CPU time limits were before, a user could escape them by
+ issuing in the shell (sh/bash/zsh) "ulimit -t 0", and then the user's
+ process was not ever killed.
+
+ Attached is a trivial patch to fix that. Simply moving the check to a
+ slightly earlier location (specifically, before the line that actually
+ assigns the limit - *old_rlim = new_rlim), does the trick.
+
+ Do note that at least the zsh (but not ash, dash, or bash) shell has the
+ problem of "caching" the limits set by the ulimit command, so when running
+ zsh the fix will not immediately be evident - after entering "ulimit -t 0",
+ "ulimit -a" will show "-t: cpu time (seconds) 0", even though the actual
+ limit as returned by getrlimit(...) will be 1. It can be verified by
+ opening a subshell (which will not have the values of the parent shell in
+ cache) and checking in it, or just by running a CPU intensive command like
+ "echo '65536^1048576' | bc" and verifying that it dumps core after one
+ second.
+
+ Regardless of whether that is a misfeature in the shell, perhaps it would
+ be better to return -EINVAL from setrlimit in such a case instead of
+ cheating and setting to 1, as that does not really reflect the actual state
+ of the process anymore. I do not however know what the ground for that
+ decision was in the original 2.6.17 change, and whether there would be any
+ "backward" compatibility issues, so I preferred not to touch that right
+ now.
+
+ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+Adjusted to apply to Debian's 2.6.18 by dann frazier <dannf@debian.org>
+
+diff -urpN linux-source-2.6.18.orig/kernel/sys.c linux-source-2.6.18/kernel/sys.c
+--- linux-source-2.6.18.orig/kernel/sys.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/kernel/sys.c 2008-04-04 18:04:09.000000000 -0600
+@@ -1807,6 +1807,16 @@ asmlinkage long sys_setrlimit(unsigned i
+ if (retval)
+ return retval;
+
++ if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
++ /*
++ * The caller is asking for an immediate RLIMIT_CPU
++ * expiry. But we use the zero value to mean "it was
++ * never set". So let's cheat and make it one second
++ * instead
++ */
++ new_rlim.rlim_cur = 1;
++ }
++
+ task_lock(current->group_leader);
+ *old_rlim = new_rlim;
+ task_unlock(current->group_leader);
+@@ -1828,15 +1838,6 @@ asmlinkage long sys_setrlimit(unsigned i
+ unsigned long rlim_cur = new_rlim.rlim_cur;
+ cputime_t cputime;
+
+- if (rlim_cur == 0) {
+- /*
+- * The caller is asking for an immediate RLIMIT_CPU
+- * expiry. But we use the zero value to mean "it was
+- * never set". So let's cheat and make it one second
+- * instead
+- */
+- rlim_cur = 1;
+- }
+ cputime = secs_to_cputime(rlim_cur);
+ read_lock(&tasklist_lock);
+ spin_lock_irq(&current->sighand->siglock);
diff --git a/trunk/2.6.18/30065_dnotify-race.patch b/trunk/2.6.18/30065_dnotify-race.patch
new file mode 100644
index 0000000..ab637bc
--- /dev/null
+++ b/trunk/2.6.18/30065_dnotify-race.patch
@@ -0,0 +1,22 @@
+diff -urpN linux-source-2.6.18.orig/fs/dnotify.c linux-source-2.6.18/fs/dnotify.c
+--- linux-source-2.6.18.orig/fs/dnotify.c 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/fs/dnotify.c 2008-04-09 13:50:42.000000000 -0600
+@@ -20,6 +20,7 @@
+ #include <linux/init.h>
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
++#include <linux/file.h>
+
+ int dir_notify_enable __read_mostly = 1;
+
+@@ -92,6 +93,10 @@ int fcntl_dirnotify(int fd, struct file
+ prev = &odn->dn_next;
+ }
+
++ /* we'd lost the race with close(), sod off silently */
++ if (fcheck(fd) != filp)
++ goto out_free;
++
+ error = f_setown(filp, current->pid, 0);
+ if (error)
+ goto out_free;