From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31CCD2931F5 for ; Sun, 26 Jul 2026 07:29:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.197 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785050978; cv=none; b=A6opBmukt5lF7IlCuDg3ge/TZn6nv88hZjk/W6ayp0cOZmWiy4GwuvKkHqtzJunnTojE8Fgo5lahwr8oPI7YVMgKbs+Zh4n30eM9UgDQE8k3ZY76ek91UVv4q/7oU5df4vqWmz0HlOh7P7sbtmHtC8lIuo7a16EOsKMUdRMtWik= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785050978; c=relaxed/simple; bh=5jXq0GZlDPqXe9QYO7516/qJ2Yjqus/4yk5N0rSWcys=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=HB0TkJDxJnt/3LWO36ONImJZ+FUJsjPS8GUCxAD6VVRYR0QR77lT6UB2WnfulCTDqjwPHky+IcYHxelH5Ri7G3YWD1PU7HiRAZ1G9KvXA3VmpFxrQo8Y8jhOypn3VfQzHrxWUYMXIzrt7w3bv2/H99z2llzjC8iGm2e5MqYFkMo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--souravpanda.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wnBgU6+1; arc=none smtp.client-ip=209.85.214.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--souravpanda.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wnBgU6+1" Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2ccb6823efcso15769835ad.0 for ; Sun, 26 Jul 2026 00:29:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785050976; x=1785655776; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:mime-version:date:from :to:cc:subject:date:message-id:reply-to:content-type; bh=SDlUu4mOxq4M4aJlUrvDjlrtRU9+dmLR8ifDAla/1p4=; b=wnBgU6+1P3O+FHG+nqBCYPLdXm49hdbSY+OkB27+vQ5UqboZTee5FHrfmo6y55IfI3 6T+rfbnWyb5rpWohVVii+AreC6tKDtFPASbu7LN9iOdkl4nx0fACVwRWZQGhJFbFOm8r 6QnhkkmXukXo6pFFUjCg5ae4xA4vdIl3mwIWNoTqN2mUD5z0TEOMks2YeIvNPAyeQkpT 4LpNKgXJ2yjuex1YcyJ02j+Bp8eAKVgTySkSh1Ng4EnAhzYpR//GH8iEXPScTB500tzJ 0eIsFIVIwrH42vq1QhsSWm4YwN8EdGD2Utop1tXOwAh5p0ITIyEACBroLrTMfkCEgtwa E47Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785050976; x=1785655776; h=content-type:cc:to:from:subject:message-id:mime-version:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=SDlUu4mOxq4M4aJlUrvDjlrtRU9+dmLR8ifDAla/1p4=; b=cR5F0XuXcwZL0IyzhF8DCbRNSDeBFg27T6aIXeDLfk20jpAiLf+iHv/lOFi5jS8Jyj hXH78r7wJG3mlFcNmPAKn0ryJipc8A7Odut3CzvbsKS8DWZVVIYIEoRj3TMttafFFjYj EgCkHb8FrfKTB2RN+d4WEJlFrdyW0XnS9LbrP23mjTo10EIJ/iNsdNhyonjpZf8azssA 53sux2Bi3VQtu8HO9YEHamrETZ4iDZnTNxjP8V0Rmo/08MoaxMwNphU4A4Ms234W6qEo qBk/NcJ/epTS4OV7SiYoq8AkP7zRivEY2r7yOV8nOq2Lnsuc5N3mWX0FhOEwqP3WL0Z+ p/GA== X-Forwarded-Encrypted: i=1; AHgh+RpBD27DAca1VX6PkwOVI6+r+K9cBiR2gutbvAq9CsIhgVZ4NCmcK+dguAcuQzFTNmdEDEQIRAgf1AL9qdY=@vger.kernel.org X-Gm-Message-State: AOJu0YxgF0DmKiK/H12tnLO7fzXt/pN7Gz0nB/ItT9qphiJrAWExlILg zHur4W240F56ijMBGnh07Y2SnHs6rKZFrdWQAeTo2P3tZv1Vza2LnLVTqHY4HXyKJU83n76/s23 UAmOMCwQNgzV0dWPPMX6gwe2Q8A== X-Received: from plps7.prod.google.com ([2002:a17:902:9887:b0:2c7:f7de:469]) (user=souravpanda job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2444:b0:2ca:bf68:2a54 with SMTP id d9443c01a7336-2cfde84e35fmr38208595ad.22.1785050976224; Sun, 26 Jul 2026 00:29:36 -0700 (PDT) Date: Sun, 26 Jul 2026 07:29:34 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.55.0.229.g6434b31f56-goog Message-ID: <20260726072935.3513996-1-souravpanda@google.com> Subject: [PATCH v4] mm/hugetlb_cma: Fix null nodemask dereference in hugetlb_cma_alloc_frozen_folio From: Sourav Panda To: muchun.song@linux.dev, osalvador@suse.de, akpm@linux-foundation.org Cc: david@kernel.org, surenb@google.com, fvdl@google.com, gthelen@google.com, souravpanda@google.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" 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: 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 --- 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