]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
vm patch for .22 and .23
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 6 Feb 2008 19:34:21 +0000 (11:34 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 6 Feb 2008 19:34:21 +0000 (11:34 -0800)
queue-2.6.23/series
queue-2.6.23/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch [new file with mode: 0644]
review-2.6.22/series
review-2.6.22/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch [new file with mode: 0644]

index be8270153eebfb4caf35565526001605da6b3965..059fcb1fcf335de0898b4f8fcd0f7d0b8715d0f5 100644 (file)
@@ -57,3 +57,4 @@ vm-security-add-security-hook-to-do_brk.patch
 security-protect-from-stack-expantion-into-low-vm-addresses.patch
 md-fix-data-corruption-when-a-degraded-raid5-array-is-reshaped.patch
 knfsd-allow-nfsv2-3-write-calls-to-succeed-when-krb5i-etc-is-used.patch
+vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch
diff --git a/queue-2.6.23/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch b/queue-2.6.23/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch
new file mode 100644 (file)
index 0000000..db5ec2a
--- /dev/null
@@ -0,0 +1,142 @@
+From 2f98735c9c24ea1f0d40a364d4e63611b689b795 Mon Sep 17 00:00:00 2001
+From: Nick Piggin <npiggin@suse.de>
+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 <npiggin@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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
+@@ -2217,7 +2217,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 = protection_map[vma->vm_flags & 7];
+       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;
+ }
index b4d9b71b1177aa6185a656d041ee6419e1d67368..c3233ee97d4ad1fff3a898ddab45800a5ccd9414 100644 (file)
@@ -24,3 +24,4 @@ cxgb-fix-stats.patch
 chelsio-fix-skb-dev-setting.patch
 powerpc-fix-invalid-semicolon-after-if-statement.patch
 acpi-apply-quirk_ich6_lpc_acpi-to-more-ich8-and-ich9.patch
+vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch
diff --git a/review-2.6.22/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch b/review-2.6.22/vm-audit-add-vm_dontexpand-to-mmap-for-drivers-that-need-it.patch
new file mode 100644 (file)
index 0000000..4f3d69f
--- /dev/null
@@ -0,0 +1,142 @@
+From 2f98735c9c24ea1f0d40a364d4e63611b689b795 Mon Sep 17 00:00:00 2001
+From: Nick Piggin <npiggin@suse.de>
+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 <npiggin@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/drm/drm_vm.c       |    2 ++
+ drivers/char/mspec.c            |    3 ++-
+ fs/ncpfs/mmap.c                 |    3 ---
+ 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, 14 insertions(+), 15 deletions(-)
+
+--- a/drivers/char/drm/drm_vm.c
++++ b/drivers/char/drm/drm_vm.c
+@@ -520,6 +520,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);
+@@ -669,6 +670,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
+@@ -265,7 +265,8 @@ mspec_mmap(struct file *file, struct vm_
+       vdata->refcnt = ATOMIC_INIT(1);
+       vma->vm_private_data = vdata;
+-      vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED | VM_PFNMAP);
++      vma->vm_flags |= (VM_IO | VM_LOCKED | 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
+@@ -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;
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -91,6 +91,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);
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2157,7 +2157,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 = protection_map[vma->vm_flags & 7];
+       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;
+ }