mirror of https://github.com/torvalds/linux.git
usercopy: Remove folio references from check_heap_object()
Use page_slab() instead of virt_to_folio() followed by folio_slab(). We do end up calling compound_head() twice for non-slab copies, but that will not be a problem once we allocate memdescs separately. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Kees Cook <kees@kernel.org> Cc: Gustavo A. R. Silva <gustavoars@kernel.org> Cc: linux-hardening@vger.kernel.org Link: https://patch.msgid.link/20251113000932.1589073-14-willy@infradead.org Reviewed-by: Harry Yoo <harry.yoo@oracle.com> Reviewed-by: Kees Cook <kees@kernel.org> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
This commit is contained in:
parent
025f5b870b
commit
5934b1be8d
|
|
@ -164,7 +164,8 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
|
||||||
{
|
{
|
||||||
unsigned long addr = (unsigned long)ptr;
|
unsigned long addr = (unsigned long)ptr;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
struct folio *folio;
|
struct page *page;
|
||||||
|
struct slab *slab;
|
||||||
|
|
||||||
if (is_kmap_addr(ptr)) {
|
if (is_kmap_addr(ptr)) {
|
||||||
offset = offset_in_page(ptr);
|
offset = offset_in_page(ptr);
|
||||||
|
|
@ -189,16 +190,23 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
|
||||||
if (!virt_addr_valid(ptr))
|
if (!virt_addr_valid(ptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
folio = virt_to_folio(ptr);
|
page = virt_to_page(ptr);
|
||||||
|
slab = page_slab(page);
|
||||||
if (folio_test_slab(folio)) {
|
if (slab) {
|
||||||
/* Check slab allocator for flags and size. */
|
/* Check slab allocator for flags and size. */
|
||||||
__check_heap_object(ptr, n, folio_slab(folio), to_user);
|
__check_heap_object(ptr, n, slab, to_user);
|
||||||
} else if (folio_test_large(folio)) {
|
} else if (PageCompound(page)) {
|
||||||
offset = ptr - folio_address(folio);
|
page = compound_head(page);
|
||||||
if (n > folio_size(folio) - offset)
|
offset = ptr - page_address(page);
|
||||||
|
if (n > page_size(page) - offset)
|
||||||
usercopy_abort("page alloc", NULL, to_user, offset, n);
|
usercopy_abort("page alloc", NULL, to_user, offset, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cannot check non-compound pages. They might be part of
|
||||||
|
* a large allocation, in which case crossing a page boundary
|
||||||
|
* is fine.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,
|
DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue