Re: [PATCH v2] mm/hugetlb: Fix null nodemask in alloc_fresh_hugetlb_folio

From: Sourav Panda

Date: Sun Jul 05 2026 - 01:40:59 EST


On Sat, Jul 4, 2026 at 5:49 PM Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> On Sat, 4 Jul 2026 17:49:30 +0000 Sourav Panda <souravpanda@xxxxxxxxxx> wrote:
>
> > alloc_buddy_hugetlb_folio_with_mpol() can pass a NULL nodemask to
> > alloc_fresh_hugetlb_folio() as a fallback to allocate from all
> > nodes. If order is gigantic, alloc_fresh_hugetlb_folio() propagates
> > the NULL nodemask down to hugetlb_cma_alloc_frozen_folio() which blindly
> > dereferences it in for_each_node_mask(), leading to a null pointer
> > dereference.
> >
> > Similarly, if the CMA allocation fails, the fallback
> > alloc_contig_frozen_pages() is also called with a NULL nodemask,
> > which may cause issues.
> >
> > Fix this by explicitly checking if nodemask is NULL in
> > alloc_fresh_hugetlb_folio() and defaulting to
> > cpuset_current_mems_allowed. This ensures that both the CMA and
> > contiguous allocators receive a valid nodemask.
> >
> > Additionally, this patch adds a missing node_isset(nid, *nodemask) check
> > in hugetlb_cma_alloc_frozen_folio() to ensure the initial node allocation
> > attempt respects the memory policy.
>
> Thanks, bu the changelog still doesn't explain the userspace visible
> effects of the bug :( Important when proposing a cc:stable bugfix.
>
> So can you please condense and include the info you sent in reply to
> my v1 question?
>

Absolutely! Thanks for shepherding it :)

I will send v3 addressing this and Sashiko's latest concern.

>
> Also, Sashiko is saying stuff, as usual:
> https://sashiko.dev/#/patchset/20260704174930.2885785-1-souravpanda@xxxxxxxxxx

Sashiko's concurrency concern is valid and can be handled with the
read_mems_allowed_begin() ... read_mems_allowed_retry() seq loop pattern.

I will send v3 with the following changes:

+ nodemask_t local_node_mask;
+
+ if (!nmask) {
+ unsigned int cpuset_mems_cookie;
+
+ do {
+ cpuset_mems_cookie = read_mems_allowed_begin();
+ local_node_mask = cpuset_current_mems_allowed;
+ } while (read_mems_allowed_retry(cpuset_mems_cookie));
+
+ nmask = &local_node_mask;
+ }