Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
@ 2026-07-26  7:29 Sourav Panda
  2026-07-28  0:57 ` Andrew Morton
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Sourav Panda @ 2026-07-26  7:29 UTC (permalink / raw)
  To: muchun.song, osalvador, akpm
  Cc: david, surenb, fvdl, gthelen, souravpanda, linux-mm, linux-kernel

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() via
alloc_gigantic_frozen_folio().

hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
leading to a null pointer dereference kernel panic.

Fix this by checking if nodemask is NULL in
hugetlb_cma_alloc_frozen_folio() and defaulting it to
node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
back to any node with memory, keeping behavior consistent with
alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().

From a userspace perspective, this bug allows an unprivileged user to
crash the kernel (trigger a panic) by requesting a gigantic hugepage
allocation with MPOL_PREFERRED_MANY on a system where CMA is only
configured on a subset of NUMA nodes.

This can be reproduced by booting a VM with two NUMA nodes, restricting
CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
hugepagesz=1G hugepages=0), and running a program that allocates a
1GB hugepage area without reserving, restricts allocation to Node 0
using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:

  void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
                   MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
                   MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
  unsigned long nodemask = 1; /* Node 0 */
  mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
        sizeof(nodemask) * 8, 0);
  memset(ptr, 0, 1UL << 30); /* Trigger fault */

This results in a NULL pointer dereference:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  Oops: Oops: 0000 [#1] SMP NOPTI
  RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
  Call Trace:
   <TASK>
   only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
   alloc_surplus_hugetlb_folio+0x6d/0x100
   alloc_hugetlb_folio+0x3c5/0x660
   hugetlb_no_page+0x3d9/0x650

Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
Cc: stable@vger.kernel.org
Signed-off-by: Sourav Panda <souravpanda@google.com>
---
Changes in v4:
- Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
  As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
  not prevent false-positive allocation failures without complex retry loops,
  and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
  NULL nodemasks safely internally.
- Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
  by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
  HugeTLB allocators clean and consistent.
- v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
- v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
- v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/

 mm/hugetlb_cma.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
index 39344d6c78d8..5744de0ceeb7 100644
--- a/mm/hugetlb_cma.c
+++ b/mm/hugetlb_cma.c
@@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
 	if (!hugetlb_cma_size)
 		return NULL;
 
-	if (hugetlb_cma[nid])
+	if (!nodemask)
+		nodemask = &node_states[N_MEMORY];
+
+	if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
 		page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
 
 	if (!page && !(gfp_mask & __GFP_THISNODE)) {
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-07-26  7:29 [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio Sourav Panda
@ 2026-07-28  0:57 ` Andrew Morton
  2026-08-03  6:37   ` Sourav Panda
  2026-08-03  9:48 ` Anshuman Khandual
  2026-08-05 20:24 ` Usama Arif
  2 siblings, 1 reply; 14+ messages in thread
From: Andrew Morton @ 2026-07-28  0:57 UTC (permalink / raw)
  To: Sourav Panda
  Cc: muchun.song, osalvador, david, surenb, fvdl, gthelen, linux-mm,
	linux-kernel, Usama Arif, Shakeel Butt, Kefeng Wang

On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> alloc_gigantic_frozen_folio().
> 
> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> leading to a null pointer dereference kernel panic.
> 
> Fix this by checking if nodemask is NULL in
> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> back to any node with memory, keeping behavior consistent with
> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> 
> >From a userspace perspective, this bug allows an unprivileged user to
> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> configured on a subset of NUMA nodes.
> 
> This can be reproduced by booting a VM with two NUMA nodes, restricting
> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> hugepagesz=1G hugepages=0), and running a program that allocates a
> 1GB hugepage area without reserving, restricts allocation to Node 0
> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> 
>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
>   unsigned long nodemask = 1; /* Node 0 */
>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
>         sizeof(nodemask) * 8, 0);
>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> 
> This results in a NULL pointer dereference:
> 
>   BUG: kernel NULL pointer dereference, address: 0000000000000000
>   #PF: supervisor read access in kernel mode
>   #PF: error_code(0x0000) - not-present page
>   Oops: Oops: 0000 [#1] SMP NOPTI
>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
>   Call Trace:
>    <TASK>
>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
>    alloc_surplus_hugetlb_folio+0x6d/0x100
>    alloc_hugetlb_folio+0x3c5/0x660
>    hugetlb_no_page+0x3d9/0x650

Thanks.  I'll queue this as a hotfix while we await review.

> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")

It's a good idea to cc the people who were involved in the to-be-fixed
patch - Author and Reviewers.

>
> ...
>
> --- a/mm/hugetlb_cma.c
> +++ b/mm/hugetlb_cma.c
> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
>  	if (!hugetlb_cma_size)
>  		return NULL;
>  
> -	if (hugetlb_cma[nid])
> +	if (!nodemask)
> +		nodemask = &node_states[N_MEMORY];
> +
> +	if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
>  		page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
>  
>  	if (!page && !(gfp_mask & __GFP_THISNODE)) {
> -- 
> 2.55.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-07-28  0:57 ` Andrew Morton
@ 2026-08-03  6:37   ` Sourav Panda
  0 siblings, 0 replies; 14+ messages in thread
From: Sourav Panda @ 2026-08-03  6:37 UTC (permalink / raw)
  To: Andrew Morton
  Cc: muchun.song, osalvador, david, surenb, fvdl, gthelen, linux-mm,
	linux-kernel, Usama Arif, Shakeel Butt, Kefeng Wang,
	Vlastimil Babka, Michal Hocko, Brendan Jackman, Johannes Weiner,
	Zi Yan

On Mon, Jul 27, 2026 at 5:57 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > alloc_gigantic_frozen_folio().
> >
> > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > leading to a null pointer dereference kernel panic.
> >
> > Fix this by checking if nodemask is NULL in
> > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > back to any node with memory, keeping behavior consistent with
> > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> >
> > >From a userspace perspective, this bug allows an unprivileged user to
> > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > configured on a subset of NUMA nodes.
> >
> > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > hugepagesz=1G hugepages=0), and running a program that allocates a
> > 1GB hugepage area without reserving, restricts allocation to Node 0
> > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> >
> >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> >   unsigned long nodemask = 1; /* Node 0 */
> >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> >         sizeof(nodemask) * 8, 0);
> >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> >
> > This results in a NULL pointer dereference:
> >
> >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> >   #PF: supervisor read access in kernel mode
> >   #PF: error_code(0x0000) - not-present page
> >   Oops: Oops: 0000 [#1] SMP NOPTI
> >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> >   Call Trace:
> >    <TASK>
> >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> >    alloc_surplus_hugetlb_folio+0x6d/0x100
> >    alloc_hugetlb_folio+0x3c5/0x660
> >    hugetlb_no_page+0x3d9/0x650
>
> Thanks.  I'll queue this as a hotfix while we await review.
>
> > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
>
> It's a good idea to cc the people who were involved in the to-be-fixed
> patch - Author and Reviewers.
>

Done!

> >
> > ...
> >
> > --- a/mm/hugetlb_cma.c
> > +++ b/mm/hugetlb_cma.c
> > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> >       if (!hugetlb_cma_size)
> >               return NULL;
> >
> > -     if (hugetlb_cma[nid])
> > +     if (!nodemask)
> > +             nodemask = &node_states[N_MEMORY];
> > +
> > +     if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> >               page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> >
> >       if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > --
> > 2.55.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-07-26  7:29 [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio Sourav Panda
  2026-07-28  0:57 ` Andrew Morton
@ 2026-08-03  9:48 ` Anshuman Khandual
  2026-08-05  4:42   ` Sourav Panda
  2026-08-05 20:24 ` Usama Arif
  2 siblings, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2026-08-03  9:48 UTC (permalink / raw)
  To: Sourav Panda
  Cc: muchun.song, osalvador, akpm, david, surenb, fvdl, gthelen,
	linux-mm, linux-kernel

On Sun, Jul 26, 2026 at 07:29:34AM +0000, Sourav Panda 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() via
> alloc_gigantic_frozen_folio().
> 
> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> leading to a null pointer dereference kernel panic.

node_isset() is being addded here in this change right ? OR was there
another path via node_isset() which could have been called on a NULL
valued nodemask ? Although subsequent for_each_node_mask() could do
the required dereference as mentioned earlier.

> 
> Fix this by checking if nodemask is NULL in
> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> back to any node with memory, keeping behavior consistent with
> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
>
> From a userspace perspective, this bug allows an unprivileged user to
> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> configured on a subset of NUMA nodes.
> 
> This can be reproduced by booting a VM with two NUMA nodes, restricting
> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> hugepagesz=1G hugepages=0), and running a program that allocates a
> 1GB hugepage area without reserving, restricts allocation to Node 0
> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> 
>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
>   unsigned long nodemask = 1; /* Node 0 */
>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
>         sizeof(nodemask) * 8, 0);
>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> 
> This results in a NULL pointer dereference:
> 
>   BUG: kernel NULL pointer dereference, address: 0000000000000000
>   #PF: supervisor read access in kernel mode
>   #PF: error_code(0x0000) - not-present page
>   Oops: Oops: 0000 [#1] SMP NOPTI
>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
>   Call Trace:
>    <TASK>
>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
>    alloc_surplus_hugetlb_folio+0x6d/0x100
>    alloc_hugetlb_folio+0x3c5/0x660
>    hugetlb_no_page+0x3d9/0x650
> 
> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sourav Panda <souravpanda@google.com>
> ---
> Changes in v4:
> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
>   not prevent false-positive allocation failures without complex retry loops,
>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
>   NULL nodemasks safely internally.
> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
>   HugeTLB allocators clean and consistent.
> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> 
>  mm/hugetlb_cma.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> index 39344d6c78d8..5744de0ceeb7 100644
> --- a/mm/hugetlb_cma.c
> +++ b/mm/hugetlb_cma.c
> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
>  	if (!hugetlb_cma_size)
>  		return NULL;
>  
> -	if (hugetlb_cma[nid])
> +	if (!nodemask)
> +		nodemask = &node_states[N_MEMORY];
> +
> +	if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
>  		page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
>  
>  	if (!page && !(gfp_mask & __GFP_THISNODE)) {
> -- 
> 2.55.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-03  9:48 ` Anshuman Khandual
@ 2026-08-05  4:42   ` Sourav Panda
  2026-08-06  2:29     ` Anshuman Khandual
  0 siblings, 1 reply; 14+ messages in thread
From: Sourav Panda @ 2026-08-05  4:42 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: muchun.song, osalvador, akpm, david, surenb, fvdl, gthelen,
	linux-mm, linux-kernel

On Mon, Aug 3, 2026 at 2:48 AM Anshuman Khandual
<anshuman.khandual@arm.com> wrote:
>
> On Sun, Jul 26, 2026 at 07:29:34AM +0000, Sourav Panda 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() via
> > alloc_gigantic_frozen_folio().
> >
> > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > leading to a null pointer dereference kernel panic.
>
> node_isset() is being addded here in this change right ? OR was there
> another path via node_isset() which could have been called on a NULL
> valued nodemask ? Although subsequent for_each_node_mask() could do
> the required dereference as mentioned earlier.
>

Thanks for the review, Anshuman!

Sashiko [1] suggested adding node_isset(nid, *nodemask) in v1 because
without it, hugetlb_cma_alloc_frozen_folio() could allocate from a node
without checking whether it is actually allowed by the caller's memory
policy / nodemask.

Once we added that check, both node_isset(nid, *nodemask) and
for_each_node_mask(node, *nodemask) became potential NULL pointer
dereferences when nodemask is NULL.

[1] https://sashiko.dev/#/patchset/20260702215713.627941-1-souravpanda@google.com

Thanks!
Sourav


> >
> > Fix this by checking if nodemask is NULL in
> > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > back to any node with memory, keeping behavior consistent with
> > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> >
> > From a userspace perspective, this bug allows an unprivileged user to
> > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > configured on a subset of NUMA nodes.
> >
> > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > hugepagesz=1G hugepages=0), and running a program that allocates a
> > 1GB hugepage area without reserving, restricts allocation to Node 0
> > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> >
> >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> >   unsigned long nodemask = 1; /* Node 0 */
> >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> >         sizeof(nodemask) * 8, 0);
> >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> >
> > This results in a NULL pointer dereference:
> >
> >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> >   #PF: supervisor read access in kernel mode
> >   #PF: error_code(0x0000) - not-present page
> >   Oops: Oops: 0000 [#1] SMP NOPTI
> >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> >   Call Trace:
> >    <TASK>
> >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> >    alloc_surplus_hugetlb_folio+0x6d/0x100
> >    alloc_hugetlb_folio+0x3c5/0x660
> >    hugetlb_no_page+0x3d9/0x650
> >
> > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Sourav Panda <souravpanda@google.com>
> > ---
> > Changes in v4:
> > - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> >   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> >   not prevent false-positive allocation failures without complex retry loops,
> >   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> >   NULL nodemasks safely internally.
> > - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> >   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> >   HugeTLB allocators clean and consistent.
> > - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> >
> >  mm/hugetlb_cma.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > index 39344d6c78d8..5744de0ceeb7 100644
> > --- a/mm/hugetlb_cma.c
> > +++ b/mm/hugetlb_cma.c
> > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> >       if (!hugetlb_cma_size)
> >               return NULL;
> >
> > -     if (hugetlb_cma[nid])
> > +     if (!nodemask)
> > +             nodemask = &node_states[N_MEMORY];
> > +
> > +     if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> >               page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> >
> >       if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > --
> > 2.55.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-07-26  7:29 [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio Sourav Panda
  2026-07-28  0:57 ` Andrew Morton
  2026-08-03  9:48 ` Anshuman Khandual
@ 2026-08-05 20:24 ` Usama Arif
  2026-08-05 23:05   ` Sourav Panda
  2026-08-06  2:47   ` Anshuman Khandual
  2 siblings, 2 replies; 14+ messages in thread
From: Usama Arif @ 2026-08-05 20:24 UTC (permalink / raw)
  To: Sourav Panda
  Cc: Usama Arif, muchun.song, osalvador, akpm, david, surenb, fvdl,
	gthelen, linux-mm, linux-kernel

On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> alloc_gigantic_frozen_folio().
> 
> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> leading to a null pointer dereference kernel panic.
> 
> Fix this by checking if nodemask is NULL in
> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> back to any node with memory, keeping behavior consistent with
> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> 
> >From a userspace perspective, this bug allows an unprivileged user to
> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> configured on a subset of NUMA nodes.
> 
> This can be reproduced by booting a VM with two NUMA nodes, restricting
> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> hugepagesz=1G hugepages=0), and running a program that allocates a
> 1GB hugepage area without reserving, restricts allocation to Node 0
> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> 
>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
>   unsigned long nodemask = 1; /* Node 0 */
>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
>         sizeof(nodemask) * 8, 0);
>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> 
> This results in a NULL pointer dereference:
> 
>   BUG: kernel NULL pointer dereference, address: 0000000000000000
>   #PF: supervisor read access in kernel mode
>   #PF: error_code(0x0000) - not-present page
>   Oops: Oops: 0000 [#1] SMP NOPTI
>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
>   Call Trace:
>    <TASK>
>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
>    alloc_surplus_hugetlb_folio+0x6d/0x100
>    alloc_hugetlb_folio+0x3c5/0x660
>    hugetlb_no_page+0x3d9/0x650
> 
> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> Cc: stable@vger.kernel.org
> Signed-off-by: Sourav Panda <souravpanda@google.com>
> ---
> Changes in v4:
> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
>   not prevent false-positive allocation failures without complex retry loops,
>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
>   NULL nodemasks safely internally.
> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
>   HugeTLB allocators clean and consistent.
> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> 
>  mm/hugetlb_cma.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> index 39344d6c78d8..5744de0ceeb7 100644
> --- a/mm/hugetlb_cma.c
> +++ b/mm/hugetlb_cma.c
> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
>  	if (!hugetlb_cma_size)
>  		return NULL;
>  
> -	if (hugetlb_cma[nid])
> +	if (!nodemask)
> +		nodemask = &node_states[N_MEMORY];

Hi Sourav,

hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
is only available on node 1. This will no now allow allocating a gigantic page
on node 1 when its explicitly not allowed?

Would it not be better to check cpuset as well?

Thanks,
Usama

> +
> +	if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
>  		page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
>  
>  	if (!page && !(gfp_mask & __GFP_THISNODE)) {
> -- 
> 2.55.0
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-05 20:24 ` Usama Arif
@ 2026-08-05 23:05   ` Sourav Panda
  2026-08-06  2:47   ` Anshuman Khandual
  1 sibling, 0 replies; 14+ messages in thread
From: Sourav Panda @ 2026-08-05 23:05 UTC (permalink / raw)
  To: Usama Arif
  Cc: muchun.song, osalvador, akpm, david, surenb, fvdl, gthelen,
	linux-mm, linux-kernel

On Wed, Aug 5, 2026 at 1:24 PM Usama Arif <usama.arif@linux.dev> wrote:
>
> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > alloc_gigantic_frozen_folio().
> >
> > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > leading to a null pointer dereference kernel panic.
> >
> > Fix this by checking if nodemask is NULL in
> > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > back to any node with memory, keeping behavior consistent with
> > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> >
> > >From a userspace perspective, this bug allows an unprivileged user to
> > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > configured on a subset of NUMA nodes.
> >
> > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > hugepagesz=1G hugepages=0), and running a program that allocates a
> > 1GB hugepage area without reserving, restricts allocation to Node 0
> > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> >
> >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> >   unsigned long nodemask = 1; /* Node 0 */
> >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> >         sizeof(nodemask) * 8, 0);
> >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> >
> > This results in a NULL pointer dereference:
> >
> >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> >   #PF: supervisor read access in kernel mode
> >   #PF: error_code(0x0000) - not-present page
> >   Oops: Oops: 0000 [#1] SMP NOPTI
> >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> >   Call Trace:
> >    <TASK>
> >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> >    alloc_surplus_hugetlb_folio+0x6d/0x100
> >    alloc_hugetlb_folio+0x3c5/0x660
> >    hugetlb_no_page+0x3d9/0x650
> >
> > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Sourav Panda <souravpanda@google.com>
> > ---
> > Changes in v4:
> > - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> >   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> >   not prevent false-positive allocation failures without complex retry loops,
> >   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> >   NULL nodemasks safely internally.
> > - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> >   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> >   HugeTLB allocators clean and consistent.
> > - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> >
> >  mm/hugetlb_cma.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > index 39344d6c78d8..5744de0ceeb7 100644
> > --- a/mm/hugetlb_cma.c
> > +++ b/mm/hugetlb_cma.c
> > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> >       if (!hugetlb_cma_size)
> >               return NULL;
> >
> > -     if (hugetlb_cma[nid])
> > +     if (!nodemask)
> > +             nodemask = &node_states[N_MEMORY];
>
> Hi Sourav,
>
> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> is only available on node 1. This will no now allow allocating a gigantic page
> on node 1 when its explicitly not allowed?
>
> Would it not be better to check cpuset as well?
>
> Thanks,
> Usama
>

Hi Usama,

In v2 and v3 of this patch series, we actually used
&cpuset_current_mems_allowed (adding a seqcount retry loop in v3 to
safely read it without torn reads). However, during the v3 review,
concerns about using cpuset_current_mems_allowed, noting potential
false-positive allocation issues.

- v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
- v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
- v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/

Let me know if you prefer I add it back!

Thanks!
Sourav

> > +
> > +     if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> >               page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> >
> >       if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > --
> > 2.55.0
> >


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-05  4:42   ` Sourav Panda
@ 2026-08-06  2:29     ` Anshuman Khandual
  0 siblings, 0 replies; 14+ messages in thread
From: Anshuman Khandual @ 2026-08-06  2:29 UTC (permalink / raw)
  To: Sourav Panda
  Cc: muchun.song, osalvador, akpm, david, surenb, fvdl, gthelen,
	linux-mm, linux-kernel

On Tue, Aug 04, 2026 at 09:42:45PM -0700, Sourav Panda wrote:
> On Mon, Aug 3, 2026 at 2:48 AM Anshuman Khandual
> <anshuman.khandual@arm.com> wrote:
> >
> > On Sun, Jul 26, 2026 at 07:29:34AM +0000, Sourav Panda 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() via
> > > alloc_gigantic_frozen_folio().
> > >
> > > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > > leading to a null pointer dereference kernel panic.
> >
> > node_isset() is being addded here in this change right ? OR was there
> > another path via node_isset() which could have been called on a NULL
> > valued nodemask ? Although subsequent for_each_node_mask() could do
> > the required dereference as mentioned earlier.
> >
> 
> Thanks for the review, Anshuman!
> 
> Sashiko [1] suggested adding node_isset(nid, *nodemask) in v1 because
> without it, hugetlb_cma_alloc_frozen_folio() could allocate from a node
> without checking whether it is actually allowed by the caller's memory
> policy / nodemask.

Fair enough.

> 
> Once we added that check, both node_isset(nid, *nodemask) and
> for_each_node_mask(node, *nodemask) became potential NULL pointer
> dereferences when nodemask is NULL.

Got it, thanks !

> 
> [1] https://sashiko.dev/#/patchset/20260702215713.627941-1-souravpanda@google.com
> 
> Thanks!
> Sourav
> 
> 
> > >
> > > Fix this by checking if nodemask is NULL in
> > > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > > back to any node with memory, keeping behavior consistent with
> > > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> > >
> > > From a userspace perspective, this bug allows an unprivileged user to
> > > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > > configured on a subset of NUMA nodes.
> > >
> > > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > > hugepagesz=1G hugepages=0), and running a program that allocates a
> > > 1GB hugepage area without reserving, restricts allocation to Node 0
> > > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> > >
> > >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> > >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> > >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> > >   unsigned long nodemask = 1; /* Node 0 */
> > >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> > >         sizeof(nodemask) * 8, 0);
> > >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> > >
> > > This results in a NULL pointer dereference:
> > >
> > >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> > >   #PF: supervisor read access in kernel mode
> > >   #PF: error_code(0x0000) - not-present page
> > >   Oops: Oops: 0000 [#1] SMP NOPTI
> > >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> > >   Call Trace:
> > >    <TASK>
> > >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> > >    alloc_surplus_hugetlb_folio+0x6d/0x100
> > >    alloc_hugetlb_folio+0x3c5/0x660
> > >    hugetlb_no_page+0x3d9/0x650
> > >
> > > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Sourav Panda <souravpanda@google.com>
> > > ---
> > > Changes in v4:
> > > - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> > >   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> > >   not prevent false-positive allocation failures without complex retry loops,
> > >   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> > >   NULL nodemasks safely internally.
> > > - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> > >   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> > >   HugeTLB allocators clean and consistent.
> > > - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > > - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > > - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> > >
> > >  mm/hugetlb_cma.c | 5 ++++-
> > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > > index 39344d6c78d8..5744de0ceeb7 100644
> > > --- a/mm/hugetlb_cma.c
> > > +++ b/mm/hugetlb_cma.c
> > > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> > >       if (!hugetlb_cma_size)
> > >               return NULL;
> > >
> > > -     if (hugetlb_cma[nid])
> > > +     if (!nodemask)
> > > +             nodemask = &node_states[N_MEMORY];
> > > +
> > > +     if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> > >               page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> > >
> > >       if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > > --
> > > 2.55.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-05 20:24 ` Usama Arif
  2026-08-05 23:05   ` Sourav Panda
@ 2026-08-06  2:47   ` Anshuman Khandual
  2026-08-06  5:33     ` Sourav Panda
  1 sibling, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2026-08-06  2:47 UTC (permalink / raw)
  To: Usama Arif
  Cc: Sourav Panda, muchun.song, osalvador, akpm, david, surenb, fvdl,
	gthelen, linux-mm, linux-kernel

On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > alloc_gigantic_frozen_folio().
> > 
> > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > leading to a null pointer dereference kernel panic.
> > 
> > Fix this by checking if nodemask is NULL in
> > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > back to any node with memory, keeping behavior consistent with
> > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> > 
> > >From a userspace perspective, this bug allows an unprivileged user to
> > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > configured on a subset of NUMA nodes.
> > 
> > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > hugepagesz=1G hugepages=0), and running a program that allocates a
> > 1GB hugepage area without reserving, restricts allocation to Node 0
> > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> > 
> >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> >   unsigned long nodemask = 1; /* Node 0 */
> >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> >         sizeof(nodemask) * 8, 0);
> >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> > 
> > This results in a NULL pointer dereference:
> > 
> >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> >   #PF: supervisor read access in kernel mode
> >   #PF: error_code(0x0000) - not-present page
> >   Oops: Oops: 0000 [#1] SMP NOPTI
> >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> >   Call Trace:
> >    <TASK>
> >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> >    alloc_surplus_hugetlb_folio+0x6d/0x100
> >    alloc_hugetlb_folio+0x3c5/0x660
> >    hugetlb_no_page+0x3d9/0x650
> > 
> > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Sourav Panda <souravpanda@google.com>
> > ---
> > Changes in v4:
> > - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> >   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> >   not prevent false-positive allocation failures without complex retry loops,
> >   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> >   NULL nodemasks safely internally.
> > - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> >   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> >   HugeTLB allocators clean and consistent.
> > - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> > 
> >  mm/hugetlb_cma.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > index 39344d6c78d8..5744de0ceeb7 100644
> > --- a/mm/hugetlb_cma.c
> > +++ b/mm/hugetlb_cma.c
> > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> >  	if (!hugetlb_cma_size)
> >  		return NULL;
> >  
> > -	if (hugetlb_cma[nid])
> > +	if (!nodemask)
> > +		nodemask = &node_states[N_MEMORY];
> 
> Hi Sourav,
> 
> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> is only available on node 1. This will no now allow allocating a gigantic page
> on node 1 when its explicitly not allowed?

That's fair point but should not the user be also responsible in provding a right
nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
fallback mechanism in kernel ?

> 
> Would it not be better to check cpuset as well?
> 
> Thanks,
> Usama
> 
> > +
> > +	if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> >  		page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> >  
> >  	if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > -- 
> > 2.55.0
> > 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-06  2:47   ` Anshuman Khandual
@ 2026-08-06  5:33     ` Sourav Panda
  2026-08-06 11:07       ` Usama Arif
  0 siblings, 1 reply; 14+ messages in thread
From: Sourav Panda @ 2026-08-06  5:33 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: Usama Arif, muchun.song, osalvador, akpm, david, surenb, fvdl,
	gthelen, linux-mm, linux-kernel

On Wed, Aug 5, 2026 at 7:47 PM Anshuman Khandual
<anshuman.khandual@arm.com> wrote:
>
> On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
> > On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > > alloc_gigantic_frozen_folio().
> > >
> > > hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > > node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > > leading to a null pointer dereference kernel panic.
> > >
> > > Fix this by checking if nodemask is NULL in
> > > hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > > node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > > back to any node with memory, keeping behavior consistent with
> > > alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> > >
> > > >From a userspace perspective, this bug allows an unprivileged user to
> > > crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > > allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > > configured on a subset of NUMA nodes.
> > >
> > > This can be reproduced by booting a VM with two NUMA nodes, restricting
> > > CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > > hugepagesz=1G hugepages=0), and running a program that allocates a
> > > 1GB hugepage area without reserving, restricts allocation to Node 0
> > > using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> > >
> > >   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> > >                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> > >                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> > >   unsigned long nodemask = 1; /* Node 0 */
> > >   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> > >         sizeof(nodemask) * 8, 0);
> > >   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> > >
> > > This results in a NULL pointer dereference:
> > >
> > >   BUG: kernel NULL pointer dereference, address: 0000000000000000
> > >   #PF: supervisor read access in kernel mode
> > >   #PF: error_code(0x0000) - not-present page
> > >   Oops: Oops: 0000 [#1] SMP NOPTI
> > >   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> > >   Call Trace:
> > >    <TASK>
> > >    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> > >    alloc_surplus_hugetlb_folio+0x6d/0x100
> > >    alloc_hugetlb_folio+0x3c5/0x660
> > >    hugetlb_no_page+0x3d9/0x650
> > >
> > > Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Sourav Panda <souravpanda@google.com>
> > > ---
> > > Changes in v4:
> > > - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> > >   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> > >   not prevent false-positive allocation failures without complex retry loops,
> > >   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> > >   NULL nodemasks safely internally.
> > > - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> > >   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> > >   HugeTLB allocators clean and consistent.
> > > - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > > - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > > - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> > >
> > >  mm/hugetlb_cma.c | 5 ++++-
> > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > > index 39344d6c78d8..5744de0ceeb7 100644
> > > --- a/mm/hugetlb_cma.c
> > > +++ b/mm/hugetlb_cma.c
> > > @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> > >     if (!hugetlb_cma_size)
> > >             return NULL;
> > >
> > > -   if (hugetlb_cma[nid])
> > > +   if (!nodemask)
> > > +           nodemask = &node_states[N_MEMORY];
> >
> > Hi Sourav,
> >
> > hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> > is only available on node 1. This will no now allow allocating a gigantic page
> > on node 1 when its explicitly not allowed?
>
> That's fair point but should not the user be also responsible in provding a right
> nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
> fallback mechanism in kernel ?
>

We have precedence for three options, which makes selecting one difficult :)

1) nodemask = &cpuset_current_mems_allowed is currently being used in:
       only_alloc_fresh_hugetlb_folio --> alloc_buddy_frozen_folio -->
__alloc_frozen_pages_noprof --> prepare_alloc_pages.
2) Some places use cookies with cpuset_current_mems_allowed to prevent
torn writes. But this adds complexity.
       An example would be dequeue_hugetlb_folio_nodemask()
3) node_states[N_MEMORY] is sprinkled all over the kernel (simplest).

> >
> > Would it not be better to check cpuset as well?
> >
> > Thanks,
> > Usama
> >
> > > +
> > > +   if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> > >             page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> > >
> > >     if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > > --
> > > 2.55.0
> > >


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-06  5:33     ` Sourav Panda
@ 2026-08-06 11:07       ` Usama Arif
  2026-08-07  4:11         ` Sourav Panda
  0 siblings, 1 reply; 14+ messages in thread
From: Usama Arif @ 2026-08-06 11:07 UTC (permalink / raw)
  To: Sourav Panda, Anshuman Khandual
  Cc: muchun.song, osalvador, akpm, david, surenb, fvdl, gthelen,
	linux-mm, linux-kernel



On 06/08/2026 06:33, Sourav Panda wrote:
> On Wed, Aug 5, 2026 at 7:47 PM Anshuman Khandual
> <anshuman.khandual@arm.com> wrote:
>>
>> On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
>>> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
>>>> alloc_gigantic_frozen_folio().
>>>>
>>>> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
>>>> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
>>>> leading to a null pointer dereference kernel panic.
>>>>
>>>> Fix this by checking if nodemask is NULL in
>>>> hugetlb_cma_alloc_frozen_folio() and defaulting it to
>>>> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
>>>> back to any node with memory, keeping behavior consistent with
>>>> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
>>>>
>>>> >From a userspace perspective, this bug allows an unprivileged user to
>>>> crash the kernel (trigger a panic) by requesting a gigantic hugepage
>>>> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
>>>> configured on a subset of NUMA nodes.
>>>>
>>>> This can be reproduced by booting a VM with two NUMA nodes, restricting
>>>> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
>>>> hugepagesz=1G hugepages=0), and running a program that allocates a
>>>> 1GB hugepage area without reserving, restricts allocation to Node 0
>>>> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
>>>>
>>>>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
>>>>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
>>>>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
>>>>   unsigned long nodemask = 1; /* Node 0 */
>>>>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
>>>>         sizeof(nodemask) * 8, 0);
>>>>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
>>>>
>>>> This results in a NULL pointer dereference:
>>>>
>>>>   BUG: kernel NULL pointer dereference, address: 0000000000000000
>>>>   #PF: supervisor read access in kernel mode
>>>>   #PF: error_code(0x0000) - not-present page
>>>>   Oops: Oops: 0000 [#1] SMP NOPTI
>>>>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
>>>>   Call Trace:
>>>>    <TASK>
>>>>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
>>>>    alloc_surplus_hugetlb_folio+0x6d/0x100
>>>>    alloc_hugetlb_folio+0x3c5/0x660
>>>>    hugetlb_no_page+0x3d9/0x650
>>>>
>>>> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
>>>> Cc: stable@vger.kernel.org
>>>> Signed-off-by: Sourav Panda <souravpanda@google.com>
>>>> ---
>>>> Changes in v4:
>>>> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
>>>>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
>>>>   not prevent false-positive allocation failures without complex retry loops,
>>>>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
>>>>   NULL nodemasks safely internally.
>>>> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
>>>>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
>>>>   HugeTLB allocators clean and consistent.
>>>> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
>>>> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
>>>> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
>>>>
>>>>  mm/hugetlb_cma.c | 5 ++++-
>>>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
>>>> index 39344d6c78d8..5744de0ceeb7 100644
>>>> --- a/mm/hugetlb_cma.c
>>>> +++ b/mm/hugetlb_cma.c
>>>> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
>>>>     if (!hugetlb_cma_size)
>>>>             return NULL;
>>>>
>>>> -   if (hugetlb_cma[nid])
>>>> +   if (!nodemask)
>>>> +           nodemask = &node_states[N_MEMORY];
>>>
>>> Hi Sourav,
>>>
>>> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
>>> is only available on node 1. This will no now allow allocating a gigantic page
>>> on node 1 when its explicitly not allowed?
>>
>> That's fair point but should not the user be also responsible in provding a right
>> nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
>> fallback mechanism in kernel ?
>>

I don't think the task can be made responsible for providing a CMA-aware fallback mask
here.  Userspace supplies the MPOL_PREFERRED_MANY preference, but the kernel itself
changes the second attempt to a NULL nodemask.  That permits fallback outside the
preferred policy nodes; it does not permit fallback outside the task's hardwall cpuset.

> 
> We have precedence for three options, which makes selecting one difficult :)
> 
> 1) nodemask = &cpuset_current_mems_allowed is currently being used in:
>        only_alloc_fresh_hugetlb_folio --> alloc_buddy_frozen_folio -->
> __alloc_frozen_pages_noprof --> prepare_alloc_pages.

Here I think using &cpuset_current_mems_allowed is part of the page allocator's wider cpuset handling.

> 2) Some places use cookies with cpuset_current_mems_allowed to prevent
> torn writes. But this adds complexity.
>        An example would be dequeue_hugetlb_folio_nodemask()
> 3) node_states[N_MEMORY] is sprinkled all over the kernel (simplest).
> 

I would prefer option 2.  A NULL mempolicy mask should fall back to
cpuset_current_mems_allowed, not all N_MEMORY nodes. 


>>>
>>> Would it not be better to check cpuset as well?
>>>
>>> Thanks,
>>> Usama
>>>
>>>> +
>>>> +   if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
>>>>             page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
>>>>
>>>>     if (!page && !(gfp_mask & __GFP_THISNODE)) {
>>>> --
>>>> 2.55.0
>>>>



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-06 11:07       ` Usama Arif
@ 2026-08-07  4:11         ` Sourav Panda
  2026-08-07  5:28           ` Anshuman Khandual
  0 siblings, 1 reply; 14+ messages in thread
From: Sourav Panda @ 2026-08-07  4:11 UTC (permalink / raw)
  To: Usama Arif
  Cc: Anshuman Khandual, muchun.song, osalvador, akpm, david, surenb,
	fvdl, gthelen, linux-mm, linux-kernel

On Thu, Aug 6, 2026 at 4:07 AM Usama Arif <usama.arif@linux.dev> wrote:
>
>
>
> On 06/08/2026 06:33, Sourav Panda wrote:
> > On Wed, Aug 5, 2026 at 7:47 PM Anshuman Khandual
> > <anshuman.khandual@arm.com> wrote:
> >>
> >> On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
> >>> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> >>>> alloc_gigantic_frozen_folio().
> >>>>
> >>>> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> >>>> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> >>>> leading to a null pointer dereference kernel panic.
> >>>>
> >>>> Fix this by checking if nodemask is NULL in
> >>>> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> >>>> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> >>>> back to any node with memory, keeping behavior consistent with
> >>>> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> >>>>
> >>>> >From a userspace perspective, this bug allows an unprivileged user to
> >>>> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> >>>> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> >>>> configured on a subset of NUMA nodes.
> >>>>
> >>>> This can be reproduced by booting a VM with two NUMA nodes, restricting
> >>>> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> >>>> hugepagesz=1G hugepages=0), and running a program that allocates a
> >>>> 1GB hugepage area without reserving, restricts allocation to Node 0
> >>>> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> >>>>
> >>>>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> >>>>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> >>>>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> >>>>   unsigned long nodemask = 1; /* Node 0 */
> >>>>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> >>>>         sizeof(nodemask) * 8, 0);
> >>>>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> >>>>
> >>>> This results in a NULL pointer dereference:
> >>>>
> >>>>   BUG: kernel NULL pointer dereference, address: 0000000000000000
> >>>>   #PF: supervisor read access in kernel mode
> >>>>   #PF: error_code(0x0000) - not-present page
> >>>>   Oops: Oops: 0000 [#1] SMP NOPTI
> >>>>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> >>>>   Call Trace:
> >>>>    <TASK>
> >>>>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> >>>>    alloc_surplus_hugetlb_folio+0x6d/0x100
> >>>>    alloc_hugetlb_folio+0x3c5/0x660
> >>>>    hugetlb_no_page+0x3d9/0x650
> >>>>
> >>>> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> >>>> Cc: stable@vger.kernel.org
> >>>> Signed-off-by: Sourav Panda <souravpanda@google.com>
> >>>> ---
> >>>> Changes in v4:
> >>>> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> >>>>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> >>>>   not prevent false-positive allocation failures without complex retry loops,
> >>>>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> >>>>   NULL nodemasks safely internally.
> >>>> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> >>>>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> >>>>   HugeTLB allocators clean and consistent.
> >>>> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> >>>> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> >>>> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> >>>>
> >>>>  mm/hugetlb_cma.c | 5 ++++-
> >>>>  1 file changed, 4 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> >>>> index 39344d6c78d8..5744de0ceeb7 100644
> >>>> --- a/mm/hugetlb_cma.c
> >>>> +++ b/mm/hugetlb_cma.c
> >>>> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> >>>>     if (!hugetlb_cma_size)
> >>>>             return NULL;
> >>>>
> >>>> -   if (hugetlb_cma[nid])
> >>>> +   if (!nodemask)
> >>>> +           nodemask = &node_states[N_MEMORY];
> >>>
> >>> Hi Sourav,
> >>>
> >>> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> >>> is only available on node 1. This will no now allow allocating a gigantic page
> >>> on node 1 when its explicitly not allowed?
> >>
> >> That's fair point but should not the user be also responsible in provding a right
> >> nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
> >> fallback mechanism in kernel ?
> >>
>
> I don't think the task can be made responsible for providing a CMA-aware fallback mask
> here.  Userspace supplies the MPOL_PREFERRED_MANY preference, but the kernel itself
> changes the second attempt to a NULL nodemask.  That permits fallback outside the
> preferred policy nodes; it does not permit fallback outside the task's hardwall cpuset.
>
> >
> > We have precedence for three options, which makes selecting one difficult :)
> >
> > 1) nodemask = &cpuset_current_mems_allowed is currently being used in:
> >        only_alloc_fresh_hugetlb_folio --> alloc_buddy_frozen_folio -->
> > __alloc_frozen_pages_noprof --> prepare_alloc_pages.
>
> Here I think using &cpuset_current_mems_allowed is part of the page allocator's wider cpuset handling.
>
> > 2) Some places use cookies with cpuset_current_mems_allowed to prevent
> > torn writes. But this adds complexity.
> >        An example would be dequeue_hugetlb_folio_nodemask()
> > 3) node_states[N_MEMORY] is sprinkled all over the kernel (simplest).
> >
>
> I would prefer option 2.  A NULL mempolicy mask should fall back to
> cpuset_current_mems_allowed, not all N_MEMORY nodes.
>

Sounds good Usama :)

I will send a patch that replaces nodemask = &node_states[N_MEMORY];
with the below:

+ 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));
+
+ nodemask = &local_node_mask;

Will send it out tomorrow! Let me know if anyone has any objections.

>
> >>>
> >>> Would it not be better to check cpuset as well?
> >>>
> >>> Thanks,
> >>> Usama
> >>>
> >>>> +
> >>>> +   if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> >>>>             page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> >>>>
> >>>>     if (!page && !(gfp_mask & __GFP_THISNODE)) {
> >>>> --
> >>>> 2.55.0
> >>>>
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-07  4:11         ` Sourav Panda
@ 2026-08-07  5:28           ` Anshuman Khandual
  2026-08-07  5:54             ` Sourav Panda
  0 siblings, 1 reply; 14+ messages in thread
From: Anshuman Khandual @ 2026-08-07  5:28 UTC (permalink / raw)
  To: Sourav Panda
  Cc: Usama Arif, muchun.song, osalvador, akpm, david, surenb, fvdl,
	gthelen, linux-mm, linux-kernel

On Thu, Aug 06, 2026 at 09:11:29PM -0700, Sourav Panda wrote:
> On Thu, Aug 6, 2026 at 4:07 AM Usama Arif <usama.arif@linux.dev> wrote:
> >
> >
> >
> > On 06/08/2026 06:33, Sourav Panda wrote:
> > > On Wed, Aug 5, 2026 at 7:47 PM Anshuman Khandual
> > > <anshuman.khandual@arm.com> wrote:
> > >>
> > >> On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
> > >>> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > >>>> alloc_gigantic_frozen_folio().
> > >>>>
> > >>>> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > >>>> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > >>>> leading to a null pointer dereference kernel panic.
> > >>>>
> > >>>> Fix this by checking if nodemask is NULL in
> > >>>> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > >>>> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > >>>> back to any node with memory, keeping behavior consistent with
> > >>>> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> > >>>>
> > >>>> >From a userspace perspective, this bug allows an unprivileged user to
> > >>>> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > >>>> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > >>>> configured on a subset of NUMA nodes.
> > >>>>
> > >>>> This can be reproduced by booting a VM with two NUMA nodes, restricting
> > >>>> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > >>>> hugepagesz=1G hugepages=0), and running a program that allocates a
> > >>>> 1GB hugepage area without reserving, restricts allocation to Node 0
> > >>>> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> > >>>>
> > >>>>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> > >>>>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> > >>>>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> > >>>>   unsigned long nodemask = 1; /* Node 0 */
> > >>>>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> > >>>>         sizeof(nodemask) * 8, 0);
> > >>>>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> > >>>>
> > >>>> This results in a NULL pointer dereference:
> > >>>>
> > >>>>   BUG: kernel NULL pointer dereference, address: 0000000000000000
> > >>>>   #PF: supervisor read access in kernel mode
> > >>>>   #PF: error_code(0x0000) - not-present page
> > >>>>   Oops: Oops: 0000 [#1] SMP NOPTI
> > >>>>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> > >>>>   Call Trace:
> > >>>>    <TASK>
> > >>>>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> > >>>>    alloc_surplus_hugetlb_folio+0x6d/0x100
> > >>>>    alloc_hugetlb_folio+0x3c5/0x660
> > >>>>    hugetlb_no_page+0x3d9/0x650
> > >>>>
> > >>>> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > >>>> Cc: stable@vger.kernel.org
> > >>>> Signed-off-by: Sourav Panda <souravpanda@google.com>
> > >>>> ---
> > >>>> Changes in v4:
> > >>>> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> > >>>>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> > >>>>   not prevent false-positive allocation failures without complex retry loops,
> > >>>>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> > >>>>   NULL nodemasks safely internally.
> > >>>> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> > >>>>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> > >>>>   HugeTLB allocators clean and consistent.
> > >>>> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > >>>> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > >>>> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> > >>>>
> > >>>>  mm/hugetlb_cma.c | 5 ++++-
> > >>>>  1 file changed, 4 insertions(+), 1 deletion(-)
> > >>>>
> > >>>> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > >>>> index 39344d6c78d8..5744de0ceeb7 100644
> > >>>> --- a/mm/hugetlb_cma.c
> > >>>> +++ b/mm/hugetlb_cma.c
> > >>>> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> > >>>>     if (!hugetlb_cma_size)
> > >>>>             return NULL;
> > >>>>
> > >>>> -   if (hugetlb_cma[nid])
> > >>>> +   if (!nodemask)
> > >>>> +           nodemask = &node_states[N_MEMORY];
> > >>>
> > >>> Hi Sourav,
> > >>>
> > >>> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> > >>> is only available on node 1. This will no now allow allocating a gigantic page
> > >>> on node 1 when its explicitly not allowed?
> > >>
> > >> That's fair point but should not the user be also responsible in provding a right
> > >> nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
> > >> fallback mechanism in kernel ?
> > >>
> >
> > I don't think the task can be made responsible for providing a CMA-aware fallback mask
> > here.  Userspace supplies the MPOL_PREFERRED_MANY preference, but the kernel itself
> > changes the second attempt to a NULL nodemask.  That permits fallback outside the
> > preferred policy nodes; it does not permit fallback outside the task's hardwall cpuset.
> >
> > >
> > > We have precedence for three options, which makes selecting one difficult :)
> > >
> > > 1) nodemask = &cpuset_current_mems_allowed is currently being used in:
> > >        only_alloc_fresh_hugetlb_folio --> alloc_buddy_frozen_folio -->
> > > __alloc_frozen_pages_noprof --> prepare_alloc_pages.
> >
> > Here I think using &cpuset_current_mems_allowed is part of the page allocator's wider cpuset handling.
> >
> > > 2) Some places use cookies with cpuset_current_mems_allowed to prevent
> > > torn writes. But this adds complexity.
> > >        An example would be dequeue_hugetlb_folio_nodemask()
> > > 3) node_states[N_MEMORY] is sprinkled all over the kernel (simplest).
> > >
> >
> > I would prefer option 2.  A NULL mempolicy mask should fall back to
> > cpuset_current_mems_allowed, not all N_MEMORY nodes.
> >
> 
> Sounds good Usama :)
> 
> I will send a patch that replaces nodemask = &node_states[N_MEMORY];
> with the below:
> 
> + 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));
> +
> + nodemask = &local_node_mask;

Although complexity increases with the above mechanism but probably
it might be better in terms of being compliant with task's hardwall
cpuset as explained by Usama earlier.

> 
> Will send it out tomorrow! Let me know if anyone has any objections.

I would say let's wait for a day or two before sending the respin.

> 
> >
> > >>>
> > >>> Would it not be better to check cpuset as well?
> > >>>
> > >>> Thanks,
> > >>> Usama
> > >>>
> > >>>> +
> > >>>> +   if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> > >>>>             page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> > >>>>
> > >>>>     if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > >>>> --
> > >>>> 2.55.0
> > >>>>
> >


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio
  2026-08-07  5:28           ` Anshuman Khandual
@ 2026-08-07  5:54             ` Sourav Panda
  0 siblings, 0 replies; 14+ messages in thread
From: Sourav Panda @ 2026-08-07  5:54 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: Usama Arif, muchun.song, osalvador, akpm, david, surenb, fvdl,
	gthelen, linux-mm, linux-kernel

On Thu, Aug 6, 2026 at 10:29 PM Anshuman Khandual
<anshuman.khandual@arm.com> wrote:
>
> On Thu, Aug 06, 2026 at 09:11:29PM -0700, Sourav Panda wrote:
> > On Thu, Aug 6, 2026 at 4:07 AM Usama Arif <usama.arif@linux.dev> wrote:
> > >
> > >
> > >
> > > On 06/08/2026 06:33, Sourav Panda wrote:
> > > > On Wed, Aug 5, 2026 at 7:47 PM Anshuman Khandual
> > > > <anshuman.khandual@arm.com> wrote:
> > > >>
> > > >> On Wed, Aug 05, 2026 at 01:24:42PM -0700, Usama Arif wrote:
> > > >>> On Sun, 26 Jul 2026 07:29:34 +0000 Sourav Panda <souravpanda@google.com> 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() via
> > > >>>> alloc_gigantic_frozen_folio().
> > > >>>>
> > > >>>> hugetlb_cma_alloc_frozen_folio() blindly dereferences the nodemask in
> > > >>>> node_isset(nid, *nodemask) and for_each_node_mask(node, *nodemask),
> > > >>>> leading to a null pointer dereference kernel panic.
> > > >>>>
> > > >>>> Fix this by checking if nodemask is NULL in
> > > >>>> hugetlb_cma_alloc_frozen_folio() and defaulting it to
> > > >>>> node_states[N_MEMORY]. This allows hugetlb_cma allocations to fall
> > > >>>> back to any node with memory, keeping behavior consistent with
> > > >>>> alloc_contig_frozen_pages() and alloc_buddy_frozen_folio().
> > > >>>>
> > > >>>> >From a userspace perspective, this bug allows an unprivileged user to
> > > >>>> crash the kernel (trigger a panic) by requesting a gigantic hugepage
> > > >>>> allocation with MPOL_PREFERRED_MANY on a system where CMA is only
> > > >>>> configured on a subset of NUMA nodes.
> > > >>>>
> > > >>>> This can be reproduced by booting a VM with two NUMA nodes, restricting
> > > >>>> CMA to Node 1 (e.g., hugetlb_cma=1:1G default_hugepagesz=1G
> > > >>>> hugepagesz=1G hugepages=0), and running a program that allocates a
> > > >>>> 1GB hugepage area without reserving, restricts allocation to Node 0
> > > >>>> using mbind() with MPOL_PREFERRED_MANY, and triggers a page fault:
> > > >>>>
> > > >>>>   void *ptr = mmap(NULL, 1UL << 30, PROT_READ | PROT_WRITE,
> > > >>>>                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB |
> > > >>>>                    MAP_HUGE_1GB | MAP_NORESERVE, -1, 0);
> > > >>>>   unsigned long nodemask = 1; /* Node 0 */
> > > >>>>   mbind(ptr, 1UL << 30, MPOL_PREFERRED_MANY, &nodemask,
> > > >>>>         sizeof(nodemask) * 8, 0);
> > > >>>>   memset(ptr, 0, 1UL << 30); /* Trigger fault */
> > > >>>>
> > > >>>> This results in a NULL pointer dereference:
> > > >>>>
> > > >>>>   BUG: kernel NULL pointer dereference, address: 0000000000000000
> > > >>>>   #PF: supervisor read access in kernel mode
> > > >>>>   #PF: error_code(0x0000) - not-present page
> > > >>>>   Oops: Oops: 0000 [#1] SMP NOPTI
> > > >>>>   RIP: 0010:hugetlb_cma_alloc_frozen_folio+0x75/0x120
> > > >>>>   Call Trace:
> > > >>>>    <TASK>
> > > >>>>    only_alloc_fresh_hugetlb_folio.isra.0+0x2c/0x160
> > > >>>>    alloc_surplus_hugetlb_folio+0x6d/0x100
> > > >>>>    alloc_hugetlb_folio+0x3c5/0x660
> > > >>>>    hugetlb_no_page+0x3d9/0x650
> > > >>>>
> > > >>>> Fixes: eb02f14c4a2b ("mm/hugetlb: allow overcommitting gigantic hugepages")
> > > >>>> Cc: stable@vger.kernel.org
> > > >>>> Signed-off-by: Sourav Panda <souravpanda@google.com>
> > > >>>> ---
> > > >>>> Changes in v4:
> > > >>>> - Reverted the alloc_fresh_hugetlb_folio() cpuset snapshot approach from v3.
> > > >>>>   As Muchun Song pointed out, snapshotting cpuset_current_mems_allowed does
> > > >>>>   not prevent false-positive allocation failures without complex retry loops,
> > > >>>>   and alloc_contig_frozen_pages() / alloc_buddy_frozen_folio() already handle
> > > >>>>   NULL nodemasks safely internally.
> > > >>>> - Handled NULL nodemask directly inside hugetlb_cma_alloc_frozen_folio()
> > > >>>>   by defaulting nodemask to node_states[N_MEMORY] (Option 2), keeping
> > > >>>>   HugeTLB allocators clean and consistent.
> > > >>>> - v3: https://lore.kernel.org/linux-mm/20260705175119.440599-1-souravpanda@google.com/
> > > >>>> - v2: https://lore.kernel.org/linux-mm/20260704174930.2885785-1-souravpanda@google.com/
> > > >>>> - v1: https://lore.kernel.org/linux-mm/20260702215713.627941-1-souravpanda@google.com/
> > > >>>>
> > > >>>>  mm/hugetlb_cma.c | 5 ++++-
> > > >>>>  1 file changed, 4 insertions(+), 1 deletion(-)
> > > >>>>
> > > >>>> diff --git a/mm/hugetlb_cma.c b/mm/hugetlb_cma.c
> > > >>>> index 39344d6c78d8..5744de0ceeb7 100644
> > > >>>> --- a/mm/hugetlb_cma.c
> > > >>>> +++ b/mm/hugetlb_cma.c
> > > >>>> @@ -34,7 +34,10 @@ struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
> > > >>>>     if (!hugetlb_cma_size)
> > > >>>>             return NULL;
> > > >>>>
> > > >>>> -   if (hugetlb_cma[nid])
> > > >>>> +   if (!nodemask)
> > > >>>> +           nodemask = &node_states[N_MEMORY];
> > > >>>
> > > >>> Hi Sourav,
> > > >>>
> > > >>> hmm what if cpuset.mems only allows allocation from node 0, and hugetlb CMA
> > > >>> is only available on node 1. This will no now allow allocating a gigantic page
> > > >>> on node 1 when its explicitly not allowed?
> > > >>
> > > >> That's fair point but should not the user be also responsible in provding a right
> > > >> nodemask containing CMA memory if it prefers avoiding node_states[N_MEMORY] based
> > > >> fallback mechanism in kernel ?
> > > >>
> > >
> > > I don't think the task can be made responsible for providing a CMA-aware fallback mask
> > > here.  Userspace supplies the MPOL_PREFERRED_MANY preference, but the kernel itself
> > > changes the second attempt to a NULL nodemask.  That permits fallback outside the
> > > preferred policy nodes; it does not permit fallback outside the task's hardwall cpuset.
> > >
> > > >
> > > > We have precedence for three options, which makes selecting one difficult :)
> > > >
> > > > 1) nodemask = &cpuset_current_mems_allowed is currently being used in:
> > > >        only_alloc_fresh_hugetlb_folio --> alloc_buddy_frozen_folio -->
> > > > __alloc_frozen_pages_noprof --> prepare_alloc_pages.
> > >
> > > Here I think using &cpuset_current_mems_allowed is part of the page allocator's wider cpuset handling.
> > >
> > > > 2) Some places use cookies with cpuset_current_mems_allowed to prevent
> > > > torn writes. But this adds complexity.
> > > >        An example would be dequeue_hugetlb_folio_nodemask()
> > > > 3) node_states[N_MEMORY] is sprinkled all over the kernel (simplest).
> > > >
> > >
> > > I would prefer option 2.  A NULL mempolicy mask should fall back to
> > > cpuset_current_mems_allowed, not all N_MEMORY nodes.
> > >
> >
> > Sounds good Usama :)
> >
> > I will send a patch that replaces nodemask = &node_states[N_MEMORY];
> > with the below:
> >
> > + 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));
> > +
> > + nodemask = &local_node_mask;
>
> Although complexity increases with the above mechanism but probably
> it might be better in terms of being compliant with task's hardwall
> cpuset as explained by Usama earlier.
>
> >
> > Will send it out tomorrow! Let me know if anyone has any objections.
>
> I would say let's wait for a day or two before sending the respin.
>

Ack!

Thanks Usama and Anshuman :)

> >
> > >
> > > >>>
> > > >>> Would it not be better to check cpuset as well?
> > > >>>
> > > >>> Thanks,
> > > >>> Usama
> > > >>>
> > > >>>> +
> > > >>>> +   if (hugetlb_cma[nid] && node_isset(nid, *nodemask))
> > > >>>>             page = cma_alloc_frozen_compound(hugetlb_cma[nid], order);
> > > >>>>
> > > >>>>     if (!page && !(gfp_mask & __GFP_THISNODE)) {
> > > >>>> --
> > > >>>> 2.55.0
> > > >>>>
> > >


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-08-07  5:55 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-26  7:29 [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio Sourav Panda
2026-07-28  0:57 ` Andrew Morton
2026-08-03  6:37   ` Sourav Panda
2026-08-03  9:48 ` Anshuman Khandual
2026-08-05  4:42   ` Sourav Panda
2026-08-06  2:29     ` Anshuman Khandual
2026-08-05 20:24 ` Usama Arif
2026-08-05 23:05   ` Sourav Panda
2026-08-06  2:47   ` Anshuman Khandual
2026-08-06  5:33     ` Sourav Panda
2026-08-06 11:07       ` Usama Arif
2026-08-07  4:11         ` Sourav Panda
2026-08-07  5:28           ` Anshuman Khandual
2026-08-07  5:54             ` Sourav Panda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox