From: Greg Kroah-Hartman Date: Wed, 6 Feb 2008 22:34:22 +0000 (-0800) Subject: another vm patch for .24 X-Git-Tag: v2.6.22.19~45 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d3827347e7549ff1ac8b07ace422d4dbb99afd13;p=thirdparty%2Fkernel%2Fstable-queue.git another vm patch for .24 --- diff --git a/queue-2.6.24/series b/queue-2.6.24/series index 9cbf10fe56e..3027bd3791d 100644 --- a/queue-2.6.24/series +++ b/queue-2.6.24/series @@ -1,2 +1,3 @@ dvb-cx23885-add-missing-subsystem-id-for-hauppauge-hvr1800-retail.patch slab-fix-bootstrap-on-memoryless-node.patch +vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch diff --git a/queue-2.6.24/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch b/queue-2.6.24/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch new file mode 100644 index 00000000000..ef88def7a3c --- /dev/null +++ b/queue-2.6.24/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch @@ -0,0 +1,142 @@ +From 2f98735c9c24ea1f0d40a364d4e63611b689b795 Mon Sep 17 00:00:00 2001 +From: Nick Piggin +Date: Sat, 2 Feb 2008 03:08:53 +0100 +Subject: 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 + +--- + drivers/char/drm/drm_vm.c | 2 ++ + drivers/char/mspec.c | 2 +- + fs/ncpfs/mmap.c | 4 ---- + kernel/relay.c | 1 + + mm/mmap.c | 2 +- + sound/oss/via82cxxx_audio.c | 14 ++++++-------- + sound/usb/usx2y/usX2Yhwdep.c | 2 +- + sound/usb/usx2y/usx2yhwdeppcm.c | 2 +- + 8 files changed, 13 insertions(+), 16 deletions(-) + +--- a/drivers/char/drm/drm_vm.c ++++ b/drivers/char/drm/drm_vm.c +@@ -506,6 +506,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_locked(vma); +@@ -655,6 +656,7 @@ static int drm_mmap_locked(struct file * + 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_locked(vma); +--- a/drivers/char/mspec.c ++++ b/drivers/char/mspec.c +@@ -283,7 +283,7 @@ mspec_mmap(struct file *file, struct vm_ + vdata->refcnt = ATOMIC_INIT(1); + vma->vm_private_data = vdata; + +- vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP); ++ vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND); + if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_ops = &mspec_vm_ops; +--- a/fs/ncpfs/mmap.c ++++ b/fs/ncpfs/mmap.c +@@ -50,10 +50,6 @@ static int ncp_file_mmap_fault(struct vm + pos = vmf->pgoff << PAGE_SHIFT; + + count = PAGE_SIZE; +- if ((unsigned long)vmf->virtual_address + PAGE_SIZE > area->vm_end) { +- WARN_ON(1); /* shouldn't happen? */ +- count = area->vm_end - (unsigned long)vmf->virtual_address; +- } + /* what we can read in one go */ + bufsize = NCP_SERVER(inode)->buffer_size; + +--- a/kernel/relay.c ++++ b/kernel/relay.c +@@ -92,6 +92,7 @@ static int relay_mmap_buf(struct rchan_b + 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); + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -2215,7 +2215,7 @@ int install_special_mapping(struct mm_st + vma->vm_start = addr; + vma->vm_end = addr + len; + +- vma->vm_flags = vm_flags | mm->def_flags; ++ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + + vma->vm_ops = &special_mapping_vmops; +--- a/sound/oss/via82cxxx_audio.c ++++ b/sound/oss/via82cxxx_audio.c +@@ -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 */ +--- a/sound/usb/usx2y/usX2Yhwdep.c ++++ b/sound/usb/usx2y/usX2Yhwdep.c +@@ -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; + } +--- a/sound/usb/usx2y/usx2yhwdeppcm.c ++++ b/sound/usb/usx2y/usx2yhwdeppcm.c +@@ -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; + }