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 large folio overruns

Move the compound page overrun detection out of
CONFIG_HARDENED_USERCOPY_PAGESPAN and convert it to use folios so it's
enabled for more people.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220110231530.665970-4-willy@infradead.org

authored by

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

+4 -6
+4 -6
mm/usercopy.c
··· 164 164 { 165 165 #ifdef CONFIG_HARDENED_USERCOPY_PAGESPAN 166 166 const void *end = ptr + n - 1; 167 - struct page *endpage; 168 167 bool is_reserved, is_cma; 169 168 170 169 /* ··· 192 193 /* Is the object wholly within one base page? */ 193 194 if (likely(((unsigned long)ptr & (unsigned long)PAGE_MASK) == 194 195 ((unsigned long)end & (unsigned long)PAGE_MASK))) 195 - return; 196 - 197 - /* Allow if fully inside the same compound (__GFP_COMP) page. */ 198 - endpage = virt_to_head_page(end); 199 - if (likely(endpage == page)) 200 196 return; 201 197 202 198 /* ··· 253 259 if (folio_test_slab(folio)) { 254 260 /* Check slab allocator for flags and size. */ 255 261 __check_heap_object(ptr, n, folio_slab(folio), to_user); 262 + } else if (folio_test_large(folio)) { 263 + unsigned long offset = ptr - folio_address(folio); 264 + if (offset + n > folio_size(folio)) 265 + usercopy_abort("page alloc", NULL, to_user, offset, n); 256 266 } else { 257 267 /* Verify object does not incorrectly span multiple pages. */ 258 268 check_page_span(ptr, n, folio_page(folio, 0), to_user);