lkml.org 
[lkml]   [2008]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 60/73] vm audit: add VM_DONTEXPAND to mmap for drivers that need it (CVE-2008-0007)
    2.6.23-stable review patch.  If anyone has any objections, please let us know.
    ------------------
    From: Nick Piggin <npiggin@suse.de>

    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;
    }
    --


    \
     
     \ /
      Last update: 2008-02-07 01:27    [W:0.026 / U:89.132 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site