• Roman Penyaev's avatar
    mm/vmalloc: fix size check for remap_vmalloc_range_partial() · c877818a
    Roman Penyaev authored
    commit 401592d2e095947344e10ec0623adbcd58934dd4 upstream.
    
    When VM_NO_GUARD is not set area->size includes adjacent guard page,
    thus for correct size checking get_vm_area_size() should be used, but
    not area->size.
    
    This fixes possible kernel oops when userspace tries to mmap an area on
    1 page bigger than was allocated by vmalloc_user() call: the size check
    inside remap_vmalloc_range_partial() accounts non-existing guard page
    also, so check successfully passes but vmalloc_to_page() returns NULL
    (guard page does not physically exist).
    
    The following code pattern example should trigger an oops:
    
      static int oops_mmap(struct file *file, struct vm_area_struct *vma)
      {
            void *mem;
    
            mem = vmalloc_user(4096);
            BUG_ON(!mem);
            /* Do not care about mem leak */
    
            return remap_vmalloc_range(vma, mem, 0);
      }
    
    And userspace simply mmaps size + PAGE_SIZE:
    
      mmap(NULL, 8192, PROT_WRITE|PROT_READ, MAP_PRIVATE, fd, 0);
    
    Possible candidates for oops which do not have any explicit size
    checks:
    
       *** drivers/media/usb/stkwebcam/stk-webcam.c:
       v4l_stk_mmap[789]   ret = remap_vmalloc_range(vma, sbuf->buffer, 0);
    
    Or the following one:
    
       *** drivers/video/fbdev/core/fbmem.c
       static int
       fb_mmap(struct file *file, struct vm_area_struct * vma)
            ...
            res = fb->fb_mmap(info, vma);
    
    Where fb_mmap callback calls remap_vmalloc_range() directly without any
    explicit checks:
    
       *** drivers/video/fbdev/vfb.c
       static int vfb_mmap(struct fb_info *info,
                 struct vm_area_struct *vma)
       {
           return remap_vmalloc_range(vma, (void *)info->fix.smem_start, vma->vm_pgoff);
       }
    
    Link: http://lkml.kernel.org/r/20190103145954.16942-2-rpenyaev@suse.deSigned-off-by: default avatarRoman Penyaev <rpenyaev@suse.de>
    Acked-by: default avatarMichal Hocko <mhocko@suse.com>
    Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
    Cc: Joe Perches <joe@perches.com>
    Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    c877818a
Name
Last commit
Last update
..
kasan Loading commit data...
Kconfig Loading commit data...
Kconfig.debug Loading commit data...
Makefile Loading commit data...
backing-dev.c Loading commit data...
balloon_compaction.c Loading commit data...
bootmem.c Loading commit data...
cleancache.c Loading commit data...
cma.c Loading commit data...
cma.h Loading commit data...
cma_debug.c Loading commit data...
compaction.c Loading commit data...
debug.c Loading commit data...
debug_page_ref.c Loading commit data...
dmapool.c Loading commit data...
early_ioremap.c Loading commit data...
fadvise.c Loading commit data...
failslab.c Loading commit data...
filemap.c Loading commit data...
frame_vector.c Loading commit data...
frontswap.c Loading commit data...
gup.c Loading commit data...
highmem.c Loading commit data...
hmm.c Loading commit data...
huge_memory.c Loading commit data...
hugetlb.c Loading commit data...
hugetlb_cgroup.c Loading commit data...
hwpoison-inject.c Loading commit data...
init-mm.c Loading commit data...
internal.h Loading commit data...
interval_tree.c Loading commit data...
khugepaged.c Loading commit data...
kmemleak-test.c Loading commit data...
kmemleak.c Loading commit data...
ksm.c Loading commit data...
list_lru.c Loading commit data...
maccess.c Loading commit data...
madvise.c Loading commit data...
memblock.c Loading commit data...
memcontrol.c Loading commit data...
memory-failure.c Loading commit data...
memory.c Loading commit data...
memory_hotplug.c Loading commit data...
mempolicy.c Loading commit data...
mempool.c Loading commit data...
memtest.c Loading commit data...
migrate.c Loading commit data...
mincore.c Loading commit data...
mlock.c Loading commit data...
mm_init.c Loading commit data...
mmap.c Loading commit data...
mmu_context.c Loading commit data...
mmu_notifier.c Loading commit data...
mmzone.c Loading commit data...
mprotect.c Loading commit data...
mremap.c Loading commit data...
msync.c Loading commit data...
nobootmem.c Loading commit data...
nommu.c Loading commit data...
oom_kill.c Loading commit data...
page-writeback.c Loading commit data...
page_alloc.c Loading commit data...
page_counter.c Loading commit data...
page_ext.c Loading commit data...
page_idle.c Loading commit data...
page_io.c Loading commit data...
page_isolation.c Loading commit data...
page_owner.c Loading commit data...
page_poison.c Loading commit data...
page_vma_mapped.c Loading commit data...
pagewalk.c Loading commit data...
percpu-internal.h Loading commit data...
percpu-km.c Loading commit data...
percpu-stats.c Loading commit data...
percpu-vm.c Loading commit data...
percpu.c Loading commit data...
pgtable-generic.c Loading commit data...
process_vm_access.c Loading commit data...
quicklist.c Loading commit data...
readahead.c Loading commit data...
rmap.c Loading commit data...
rodata_test.c Loading commit data...
shmem.c Loading commit data...
slab.c Loading commit data...
slab.h Loading commit data...
slab_common.c Loading commit data...
slob.c Loading commit data...
slub.c Loading commit data...
sparse-vmemmap.c Loading commit data...
sparse.c Loading commit data...
swap.c Loading commit data...
swap_cgroup.c Loading commit data...
swap_slots.c Loading commit data...
swap_state.c Loading commit data...
swapfile.c Loading commit data...
truncate.c Loading commit data...
usercopy.c Loading commit data...
userfaultfd.c Loading commit data...
util.c Loading commit data...
vmacache.c Loading commit data...
vmalloc.c Loading commit data...
vmpressure.c Loading commit data...
vmscan.c Loading commit data...
vmstat.c Loading commit data...
workingset.c Loading commit data...
z3fold.c Loading commit data...
zbud.c Loading commit data...
zpool.c Loading commit data...
zsmalloc.c Loading commit data...
zswap.c Loading commit data...