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.

usercopy: Remove HARDENED_USERCOPY_PAGESPAN

There isn't enough information to make this a useful check any more;
the useful parts of it were moved in earlier patches, so remove this
set of checks now.

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-5-willy@infradead.org

authored by

Matthew Wilcox (Oracle) and committed by
Kees Cook
1109a5d9 ab502103

+1 -73
-61
mm/usercopy.c
··· 158 158 usercopy_abort("null address", NULL, to_user, ptr, n); 159 159 } 160 160 161 - /* Checks for allocs that are marked in some way as spanning multiple pages. */ 162 - static inline void check_page_span(const void *ptr, unsigned long n, 163 - struct page *page, bool to_user) 164 - { 165 - #ifdef CONFIG_HARDENED_USERCOPY_PAGESPAN 166 - const void *end = ptr + n - 1; 167 - bool is_reserved, is_cma; 168 - 169 - /* 170 - * Sometimes the kernel data regions are not marked Reserved (see 171 - * check below). And sometimes [_sdata,_edata) does not cover 172 - * rodata and/or bss, so check each range explicitly. 173 - */ 174 - 175 - /* Allow reads of kernel rodata region (if not marked as Reserved). */ 176 - if (ptr >= (const void *)__start_rodata && 177 - end <= (const void *)__end_rodata) { 178 - if (!to_user) 179 - usercopy_abort("rodata", NULL, to_user, 0, n); 180 - return; 181 - } 182 - 183 - /* Allow kernel data region (if not marked as Reserved). */ 184 - if (ptr >= (const void *)_sdata && end <= (const void *)_edata) 185 - return; 186 - 187 - /* Allow kernel bss region (if not marked as Reserved). */ 188 - if (ptr >= (const void *)__bss_start && 189 - end <= (const void *)__bss_stop) 190 - return; 191 - 192 - /* Is the object wholly within one base page? */ 193 - if (likely(((unsigned long)ptr & (unsigned long)PAGE_MASK) == 194 - ((unsigned long)end & (unsigned long)PAGE_MASK))) 195 - return; 196 - 197 - /* 198 - * Reject if range is entirely either Reserved (i.e. special or 199 - * device memory), or CMA. Otherwise, reject since the object spans 200 - * several independently allocated pages. 201 - */ 202 - is_reserved = PageReserved(page); 203 - is_cma = is_migrate_cma_page(page); 204 - if (!is_reserved && !is_cma) 205 - usercopy_abort("spans multiple pages", NULL, to_user, 0, n); 206 - 207 - for (ptr += PAGE_SIZE; ptr <= end; ptr += PAGE_SIZE) { 208 - page = virt_to_head_page(ptr); 209 - if (is_reserved && !PageReserved(page)) 210 - usercopy_abort("spans Reserved and non-Reserved pages", 211 - NULL, to_user, 0, n); 212 - if (is_cma && !is_migrate_cma_page(page)) 213 - usercopy_abort("spans CMA and non-CMA pages", NULL, 214 - to_user, 0, n); 215 - } 216 - #endif 217 - } 218 - 219 161 static inline void check_heap_object(const void *ptr, unsigned long n, 220 162 bool to_user) 221 163 { ··· 199 257 unsigned long offset = ptr - folio_address(folio); 200 258 if (offset + n > folio_size(folio)) 201 259 usercopy_abort("page alloc", NULL, to_user, offset, n); 202 - } else { 203 - /* Verify object does not incorrectly span multiple pages. */ 204 - check_page_span(ptr, n, folio_page(folio, 0), to_user); 205 260 } 206 261 } 207 262
+1 -12
security/Kconfig
··· 160 160 copy_from_user() functions) by rejecting memory ranges that 161 161 are larger than the specified heap object, span multiple 162 162 separately allocated pages, are not on the process stack, 163 - or are part of the kernel text. This kills entire classes 163 + or are part of the kernel text. This prevents entire classes 164 164 of heap overflow exploits and similar kernel memory exposures. 165 - 166 - config HARDENED_USERCOPY_PAGESPAN 167 - bool "Refuse to copy allocations that span multiple pages" 168 - depends on HARDENED_USERCOPY 169 - depends on BROKEN 170 - help 171 - When a multi-page allocation is done without __GFP_COMP, 172 - hardened usercopy will reject attempts to copy it. There are, 173 - however, several cases of this in the kernel that have not all 174 - been removed. This config is intended to be used only while 175 - trying to find such users. 176 165 177 166 config FORTIFY_SOURCE 178 167 bool "Harden common str/mem functions against buffer overflows"