From b5492e8b4de99d5e69674834f441b21e77b146fe Mon Sep 17 00:00:00 2001 From: Robert Buchholz Date: Sun, 4 May 2008 16:38:00 +0000 Subject: Update 2.6.18 Security patches to 2.6.18.dfsg.1-18etch3, thanks dannf. svn path=/patches/; revision=77 --- trunk/2.6.18/00000_README | 14 ++- trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch | 120 +++++++++++++++++++++ .../2.6.18/30064_RLIMIT_CPU-earlier-checking.patch | 80 ++++++++++++++ trunk/2.6.18/30065_dnotify-race.patch | 22 ++++ 4 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 trunk/2.6.18/30063_mmap-VM_DONTEXPAND.patch create mode 100644 trunk/2.6.18/30064_RLIMIT_CPU-earlier-checking.patch create mode 100644 trunk/2.6.18/30065_dnotify-race.patch 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 +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + +Backported to Debian's 2.6.18 by dann frazier + +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 +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 + Signed-off-by: Linus Torvalds + +Adjusted to apply to Debian's 2.6.18 by dann frazier + +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(¤t->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 + #include + #include ++#include + + 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; -- cgit v1.2.3-65-gdbad