mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:04:43 +01:00
mm/huge_memory: fix NULL pointer deference when splitting folio
Commitc010d47f10("mm: thp: split huge page to any lower order pages") introduced an early check on the folio's order via mapping->flags before proceeding with the split work. This check introduced a bug: for shmem folios in the swap cache and truncated folios, the mapping pointer can be NULL. Accessing mapping->flags in this state leads directly to a NULL pointer dereference. This commit fixes the issue by moving the check for mapping != NULL before any attempt to access mapping->flags. Link: https://lkml.kernel.org/r/20251119235302.24773-1-richard.weiyang@gmail.com Fixes:c010d47f10("mm: thp: split huge page to any lower order pages") Signed-off-by: Wei Yang <richard.weiyang@gmail.com> Reviewed-by: Zi Yan <ziy@nvidia.com> Acked-by: David Hildenbrand (Red Hat) <david@kernel.org> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
6c96c6bd2c
commit
cff47b9e39
1 changed files with 10 additions and 12 deletions
|
|
@ -3619,6 +3619,16 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
|
|||
if (folio != page_folio(split_at) || folio != page_folio(lock_at))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Folios that just got truncated cannot get split. Signal to the
|
||||
* caller that there was a race.
|
||||
*
|
||||
* TODO: this will also currently refuse shmem folios that are in the
|
||||
* swapcache.
|
||||
*/
|
||||
if (!is_anon && !folio->mapping)
|
||||
return -EBUSY;
|
||||
|
||||
if (new_order >= folio_order(folio))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -3659,18 +3669,6 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
|
|||
gfp_t gfp;
|
||||
|
||||
mapping = folio->mapping;
|
||||
|
||||
/* Truncated ? */
|
||||
/*
|
||||
* TODO: add support for large shmem folio in swap cache.
|
||||
* When shmem is in swap cache, mapping is NULL and
|
||||
* folio_test_swapcache() is true.
|
||||
*/
|
||||
if (!mapping) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
min_order = mapping_min_folio_order(folio->mapping);
|
||||
if (new_order < min_order) {
|
||||
ret = -EINVAL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue