linux-brain/mm
Roman Penyaev 5b4e779e95 mm/vmalloc: fix size check for remap_vmalloc_range_partial()
commit 401592d2e0 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.de
Signed-off-by: Roman Penyaev <rpenyaev@suse.de>
Acked-by: Michal 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-23 13:19:49 +01:00
..
kasan kasan: fix shadow_size calculation error in kasan_module_alloc 2018-08-24 13:12:35 +02:00
Kconfig mm: don't allow deferred pages with NEED_PER_CPU_KM 2018-05-22 16:57:57 +02:00
Kconfig.debug PM / Hibernate: allow hibernation with PAGE_POISONING_ZERO 2016-09-13 02:35:27 +02:00
Makefile Disable the __builtin_return_address() warning globally after all 2016-10-12 10:23:41 -07:00
backing-dev.c block: fix double-free in the failure path of cgwb_bdi_init() 2017-02-26 11:10:52 +01:00
balloon_compaction.c mm: balloon: use general non-lru movable page feature 2016-07-26 16:19:19 -07:00
bootmem.c mm: kmemleak: avoid using __va() on addresses that don't have a lowmem mapping 2016-10-11 15:06:33 -07:00
cleancache.c cleancache: constify cleancache_ops structure 2016-01-27 09:09:57 -05:00
cma.c cma: fix calculation of aligned offset 2018-01-31 12:55:51 +01:00
cma.h mm: cma: mark cma_bitmap_maxno() inline in header 2015-08-14 15:56:32 -07:00
cma_debug.c mm/cma_debug: correct size input to bitmap function 2015-07-17 16:39:54 -07:00
compaction.c mm, compaction: fix NR_ISOLATED_* stats for pfn based migration 2017-01-12 11:39:32 +01:00
debug.c mm: get rid of vmacache_flush_all() entirely 2018-09-19 22:47:17 +02:00
debug_page_ref.c mm/page_ref: add tracepoint to track down page reference manipulation 2016-03-17 15:09:34 -07:00
dmapool.c mm: convert printk(KERN_<LEVEL> to pr_<level> 2016-03-17 15:09:34 -07:00
early_ioremap.c mm/early_ioremap: Fix boot hang with earlyprintk=efi,keep 2018-02-25 11:05:49 +01:00
fadvise.c mm/fadvise.c: fix signed overflow UBSAN complaint 2018-09-15 09:42:57 +02:00
failslab.c mm: fault-inject take over bootstrap kmem_cache check 2016-03-15 16:55:16 -07:00
filemap.c mm/filemap.c: fix NULL pointer in page_cache_tree_insert() 2018-04-24 09:34:18 +02:00
frame_vector.c mm/frame_vector.c: release a semaphore in 'get_vaddr_frames()' 2018-11-10 07:42:52 -08:00
frontswap.c mm, frontswap: convert frontswap_enabled to static key 2016-07-26 16:19:19 -07:00
gup.c mm/gup: fix gup_pmd_range() for dax 2019-03-23 13:19:41 +01:00
highmem.c mm/highmem: make nr_free_highpages() handles all highmem zones by itself 2016-05-19 19:12:14 -07:00
huge_memory.c mm/huge_memory: fix lockdep complaint on 32-bit i_size_read() 2018-12-05 19:42:36 +01:00
hugetlb.c hugetlbfs: fix races and page leaks during migration 2019-03-13 14:04:54 -07:00
hugetlb_cgroup.c mm, hugetlb_cgroup: round limit_in_bytes down to hugepage size 2016-05-20 17:58:30 -07:00
hwpoison-inject.c hwpoison: use page_cgroup_ino for filtering by memcg 2015-09-10 13:29:01 -07:00
init-mm.c mm: Add a user_ns owner to mm_struct and fix ptrace permission checks 2017-01-06 10:40:13 +01:00
internal.h mm: fix 100% CPU kswapd busyloop on unreclaimable nodes 2018-01-31 12:55:53 +01:00
interval_tree.c mm: replace vma->sharead.linear with vma->shared 2015-02-10 14:30:31 -08:00
khugepaged.c mm/khugepaged: collapse_shmem() do not crash on Compound 2018-12-05 19:42:38 +01:00
kmemcheck.c mm: convert printk(KERN_<LEVEL> to pr_<level> 2016-03-17 15:09:34 -07:00
kmemleak-test.c mm: convert printk(KERN_<LEVEL> to pr_<level> 2016-03-17 15:09:34 -07:00
kmemleak.c mm/kmemleak.c: wait for scan completion before disabling free 2018-05-30 07:50:39 +02:00
ksm.c mm/ksm: fix interaction with THP 2018-05-30 07:50:41 +02:00
list_lru.c mm/list_lru.c: fix list_lru_count_node() to be race free 2017-07-21 07:42:21 +02:00
maccess.c x86: remove more uaccess_32.h complexity 2016-05-22 17:21:27 -07:00
madvise.c mm: madvise(MADV_DODUMP): allow hugetlbfs pages 2018-10-10 08:53:20 +02:00
memblock.c mm/memblock.c: reversed logic in memblock_discard() 2017-08-30 10:21:47 +02:00
memcontrol.c memcg: remove memcg_cgroup::id from IDR on mem_cgroup_css_alloc() failure 2018-09-05 09:20:04 +02:00
memory-failure.c mm: hwpoison: fix thp split handing in soft_offline_in_use_page() 2019-03-23 13:19:49 +01:00
memory.c mm: stop leaking PageTables 2019-02-20 10:18:34 +01:00
memory_hotplug.c mm, memory_hotplug: test_pages_in_a_zone do not pass the end of zone 2019-03-13 14:04:58 -07:00
mempolicy.c numa: change get_mempolicy() to use nr_node_ids instead of MAX_NUMNODES 2019-02-27 10:06:58 +01:00
mempool.c Revert "mm, mempool: only set __GFP_NOMEMALLOC if there are free elements" 2016-07-28 16:07:41 -07:00
memtest.c memtest: remove unused header files 2015-09-08 15:35:28 -07:00
migrate.c hugetlbfs: fix races and page leaks during migration 2019-03-13 14:04:54 -07:00
mincore.c mm, swap: use offset of swap entry as key of swap cache 2016-10-07 18:46:28 -07:00
mlock.c mlock: fix mlock count can not decrease in race condition 2017-06-07 12:07:49 +02:00
mm_init.c mm: convert printk(KERN_<LEVEL> to pr_<level> 2016-03-17 15:09:34 -07:00
mmap.c mm: enforce min addr even if capable() in expand_downwards() 2019-03-05 17:57:07 +01:00
mmu_context.c mm/mmu_context, sched/core: Fix mmu_context.h assumption 2016-04-28 11:44:19 +02:00
mmu_notifier.c fix Christoph's email addresses 2016-03-17 15:09:34 -07:00
mmzone.c mm, page_alloc: inline the fast path of the zonelist iterator 2016-05-19 19:12:14 -07:00
mprotect.c x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings 2018-08-15 18:14:45 +02:00
mremap.c mremap: properly flush TLB before releasing the page 2018-10-20 09:51:31 +02:00
msync.c mm/msync: use offset_in_page macro 2015-11-05 19:34:48 -08:00
nobootmem.c mm: discard memblock data later 2017-08-24 17:12:19 -07:00
nommu.c ptrace: Don't allow accessing an undumpable mm 2017-01-06 10:40:13 +01:00
oom_kill.c oom, oom_reaper: do not enqueue same task twice 2019-02-12 19:45:02 +01:00
page-writeback.c mm/page-writeback.c: don't break integrity writeback on ->writepage() error 2019-01-26 09:38:35 +01:00
page_alloc.c mm: page_alloc: fix ref bias in page_frag_alloc() for 1-byte allocs 2019-03-23 13:19:42 +01:00
page_counter.c mm: page_counter: let page_counter_try_charge() return bool 2015-11-05 19:34:48 -08:00
page_ext.c mm/page_ext: support extra space allocation by page_ext user 2016-10-07 18:46:27 -07:00
page_idle.c mm, vmscan: move lru_lock to the node 2016-07-28 16:07:41 -07:00
page_io.c mm/page_io.c: replace some BUG_ON()s with VM_BUG_ON_PAGE() 2016-10-07 18:46:29 -07:00
page_isolation.c mm/page_isolation: fix typo: "paes" -> "pages" 2016-10-07 18:46:29 -07:00
page_owner.c mm/page_owner: don't define fields on struct page_ext by hard-coding 2016-10-07 18:46:27 -07:00
page_poison.c mm: check the return value of lookup_page_ext for all call sites 2016-06-03 15:06:22 -07:00
pagewalk.c mm/pagewalk.c: report holes in hugetlb ranges 2017-11-24 08:33:42 +01:00
percpu-km.c mm: percpu: use pr_fmt to prefix output 2016-03-17 15:09:34 -07:00
percpu-vm.c percpu: move region iterations out of pcpu_[de]populate_chunk() 2014-09-02 14:46:02 -04:00
percpu.c percpu: include linux/sched.h for cond_resched() 2018-05-09 09:50:18 +02:00
pgtable-generic.c mm/thp/migration: switch from flush_tlb_range to flush_pmd_tlb_range 2016-03-17 15:09:34 -07:00
process_vm_access.c mm: remove write/force parameters from __get_user_pages_unlocked() 2016-10-18 14:13:37 -07:00
quicklist.c fix Christoph's email addresses 2016-03-17 15:09:34 -07:00
readahead.c mm: silently skip readahead for DAX inodes 2016-08-26 17:39:35 -07:00
rmap.c mm: migration: fix migration of huge PMD shared pages 2018-11-21 09:26:03 +01:00
shmem.c tmpfs: fix uninitialized return value in shmem_link 2019-03-23 13:19:44 +01:00
slab.c slab: alien caches must not be initialized if the allocation of the alien cache failed 2019-01-16 22:12:32 +01:00
slab.h slub: move synchronize_sched out of slab_mutex on shrink 2017-03-22 12:43:38 +01:00
slab_common.c mm: don't warn about large allocations for slab 2018-12-01 09:44:19 +01:00
slob.c slub: move synchronize_sched out of slab_mutex on shrink 2017-03-22 12:43:38 +01:00
slub.c slub: make ->cpu_partial unsigned int 2018-10-03 17:01:50 -07:00
sparse-vmemmap.c treewide: replace obsolete _refok by __ref 2016-08-02 17:31:41 -04:00
sparse.c mm/memory_hotplug: set magic number to page->freelist instead of page->lru.next 2017-10-21 17:21:36 +02:00
swap.c thp: reduce usage of huge zero page's atomic counter 2016-10-07 18:46:28 -07:00
swap_cgroup.c mm, swap_cgroup: reschedule when neeed in swap_cgroup_swapoff() 2017-07-05 14:40:17 +02:00
swap_state.c mm, swap: use offset of swap entry as key of swap cache 2016-10-07 18:46:28 -07:00
swapfile.c x86/speculation/l1tf: Limit swap file size to MAX_PA/2 2018-08-15 18:14:45 +02:00
truncate.c mm: cleancache: fix corruption on missed inode invalidation 2018-12-08 13:05:09 +01:00
usercopy.c mm: usercopy: Check for module addresses 2016-09-20 16:07:39 -07:00
userfaultfd.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
util.c mm: page_mapped: don't assume compound page is huge or THP 2019-01-16 22:12:32 +01:00
vmacache.c mm: get rid of vmacache_flush_all() entirely 2018-09-19 22:47:17 +02:00
vmalloc.c mm/vmalloc: fix size check for remap_vmalloc_range_partial() 2019-03-23 13:19:49 +01:00
vmpressure.c mm: vmpressure: fix sending wrong events on underflow 2017-03-12 06:41:43 +01:00
vmscan.c mm: remove seemingly spurious reclaimability check from laptop_mode gating 2018-09-19 22:47:12 +02:00
vmstat.c mm/vmstat.c: fix outdated vmstat_text 2018-10-18 09:13:21 +02:00
workingset.c mm: workingset: fix premature shadow node shrinking with cgroups 2017-04-08 09:30:36 +02:00
z3fold.c mm/z3fold.c: avoid modifying HEADLESS page and minor cleanup 2016-06-03 16:02:55 -07:00
zbud.c mm/zbud.c: use list_last_entry() instead of list_tail_entry() 2016-01-15 11:40:52 -08:00
zpool.c mm: zsmalloc: constify struct zs_pool name 2015-11-06 17:50:42 -08:00
zsmalloc.c mm/zsmalloc.c: fix -Wunneeded-internal-declaration warning 2019-02-27 10:07:03 +01:00
zswap.c zswap: re-check zswap_is_full() after do zswap_shrink() 2018-09-05 09:20:02 +02:00