Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/usercopy: Detect vmalloc overruns

If you have a vmalloc() allocation, or an address from calling vmap(),
you cannot overrun the vm_area which describes it, regardless of the
size of the underlying allocation. This probably doesn't do much for
security because vmalloc comes with guard pages these days, but it
prevents usercopy aborts when copying to a vmap() of smaller pages.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220110231530.665970-3-willy@infradead.org

authored by

Matthew Wilcox (Oracle) and committed by
Kees Cook
0aef499f 4e140f59

+16
+16
mm/usercopy.c
··· 17 17 #include <linux/sched/task.h> 18 18 #include <linux/sched/task_stack.h> 19 19 #include <linux/thread_info.h> 20 + #include <linux/vmalloc.h> 20 21 #include <linux/atomic.h> 21 22 #include <linux/jump_label.h> 22 23 #include <asm/sections.h> ··· 236 235 if ((unsigned long)ptr + n - 1 > page_end) 237 236 usercopy_abort("kmap", NULL, to_user, 238 237 offset_in_page(ptr), n); 238 + return; 239 + } 240 + 241 + if (is_vmalloc_addr(ptr)) { 242 + struct vm_struct *area = find_vm_area(ptr); 243 + unsigned long offset; 244 + 245 + if (!area) { 246 + usercopy_abort("vmalloc", "no area", to_user, 0, n); 247 + return; 248 + } 249 + 250 + offset = ptr - area->addr; 251 + if (offset + n > get_vm_area_size(area)) 252 + usercopy_abort("vmalloc", NULL, to_user, offset, n); 239 253 return; 240 254 } 241 255