From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82AE83EA66 for ; Sun, 5 Jul 2026 19:04:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783278253; cv=none; b=up/9DjqAAFSUQvXiOvocS3OBL+ZrG4b7opyeB5rpvGxF49xCh0Nk0MYH1n4XWgh2ZBPyA6lW7WHWGQ58t5BqewwExCkOUVnIWaW9TPgCBe5VJVm+cVFKf2vzzWQ6CcUUeGqhAQhMfY7fA/4AW02zxy7vuHWE2rm0ctyTb+6V7lw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783278253; c=relaxed/simple; bh=le6Wa5G9koRZJoMMp5wMu2eyb+YfCyUFXZZ7GU59y2Q=; h=Date:From:To:Cc:Subject:Message-Id:In-Reply-To:References: Mime-Version:Content-Type; b=jqipI7k1JPrjH8kj2XxjU9OArbsCZUPvNXEG6Pg1sRXZ6+ZBSv6ak1Ul5IeA+HLepLzuyv54FUITZH7aLVkTeDDzBbonY6YjiUSImm30V+aMRKsrBeLjhz5AqVH9z5WiJGMB/SYr2qBkS3sKyERo9nolTC9U55BmSGyiu6STA1s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=AYsjz1pq; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="AYsjz1pq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B42421F000E9; Sun, 5 Jul 2026 19:04:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1783278252; bh=GZxMbMd4ZOtuqkmNi75lsrZtwZDB44oZSzF7qE5TcN0=; h=Date:From:To:Cc:Subject:In-Reply-To:References; b=AYsjz1pqlDz7VLoMS+T/hP5o5JJjOW1GiR5eXaBDml23YkCuj7R/7jq0NvXtFppBt O0ZfgKnKcJAO9GHuW8uqQs+k8+kTy7S/oB5OIy4Doa+ebTbmiK9Oci78CvrTrVmND+ viqMdnad1t1Dj5Pw+FucWDq3dRjtnubyNN7t4T0s= Date: Sun, 5 Jul 2026 12:04:11 -0700 From: Andrew Morton To: Sourav Panda Cc: muchun.song@linux.dev, osalvador@suse.de, david@kernel.org, surenb@google.com, fvdl@google.com, gthelen@google.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v3] mm/hugetlb: Fix null nodemask in alloc_fresh_hugetlb_folio Message-Id: <20260705120411.c7a34ec212cb5ae4e0939076@linux-foundation.org> In-Reply-To: <20260705175119.440599-1-souravpanda@google.com> References: <20260705175119.440599-1-souravpanda@google.com> X-Mailer: Sylpheed 3.8.0beta1 (GTK+ 2.24.33; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Sun, 5 Jul 2026 17:51:19 +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() 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 safely using a seqcount > loop to prevent torn reads. > > 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. ow. > --- a/mm/hugetlb.c > +++ b/mm/hugetlb.c > @@ -1864,6 +1864,18 @@ static struct folio *alloc_fresh_hugetlb_folio(struct hstate *h, > gfp_t gfp_mask, int nid, nodemask_t *nmask) > { > struct folio *folio; > + 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; > + } For my edification, is there anything which prevents cpuset_current_mems_allowed from changing after it has been read? So we end up with a folio on an inappropriate node? Or does that not really matter much. cpuset_current_mems_allowed is a nasty thing. It looks like a simple global variable, but appearances can be deceptive: #ifdef ... #define cpuset_current_mems_allowed (current->mems_allowed) #else #define cpuset_current_mems_allowed (node_states[N_MEMORY]) #endif Thanks, I'll queue this for a bit of testing and shall await reviewer input.