[PATCH v2] mm/hugetlb: Don't crash when allocating a folio if there are no resv
Oscar Salvador
osalvador at suse.de
Thu Jun 26 20:35:33 UTC 2025
On Thu, Jun 26, 2025 at 12:11:16PM -0700, Vivek Kasireddy wrote:
> There are cases when we try to pin a folio but discover that it has
> not been faulted-in. So, we try to allocate it in memfd_alloc_folio()
> but there is a chance that we might encounter a fatal crash/failure
> (VM_BUG_ON(!h->resv_huge_pages) in alloc_hugetlb_folio_reserve()) if
> there are no active reservations at that instant. This issue was
> reported by syzbot:
>
...
> 3) is the most common use-case where first a memfd is allocated
> followed by mmap(), user writes/updates and then the relevant folios
> are pinned (memfd_pin_folios()). The BUG this patch is fixing occurs
> in 2) because we try to pin the folios before hugetlbfs_file_mmap()
> is called. So, in this situation we try to allocate the folios
> before pinning them but since we did not make any reservations,
> resv_huge_pages would be 0, leading to this issue.
Well, if we did not make any reservations, resv_huge_pages will be 0 for sure,
right?
As I see it, this piece of code is steril, because you have to entrust making
those reservations to someone else for this to work. (Like you do in the
other patch).
But this fixes a bug, so..
> Fixes: 26a8ea80929c ("mm/hugetlb: fix memfd_pin_folios resv_huge_pages leak")
> Reported-by: syzbot+a504cb5bae4fe117ba94 at syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=a504cb5bae4fe117ba94
> Closes: https://lore.kernel.org/all/677928b5.050a0220.3b53b0.004d.GAE@google.com/T/
> Cc: Steve Sistare <steven.sistare at oracle.com>
> Cc: Muchun Song <muchun.song at linux.dev>
> Cc: David Hildenbrand <david at redhat.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Oscar Salvador <osalvador at suse.de>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
Acked-by: Oscar Salvador <osalvador at suse.de>
> ---
> mm/hugetlb.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 8746ed2fec13..a181c55f268b 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -2340,12 +2340,15 @@ struct folio *alloc_hugetlb_folio_reserve(struct hstate *h, int preferred_nid,
> struct folio *folio;
>
> spin_lock_irq(&hugetlb_lock);
> + if (!h->resv_huge_pages) {
> + spin_unlock_irq(&hugetlb_lock);
> + return NULL;
> + }
> +
> folio = dequeue_hugetlb_folio_nodemask(h, gfp_mask, preferred_nid,
> nmask);
> - if (folio) {
> - VM_BUG_ON(!h->resv_huge_pages);
> + if (folio)
> h->resv_huge_pages--;
> - }
>
> spin_unlock_irq(&hugetlb_lock);
> return folio;
> --
> 2.49.0
>
--
Oscar Salvador
SUSE Labs
More information about the dri-devel
mailing list