From: sashiko-bot@kernel.org
To: "Gregory Price" <gourry@gourry.net>
Cc: nvdimm@lists.linux.dev, kvm@vger.kernel.org, hannes@cmpxchg.org,
linux-cxl@vger.kernel.org, tj@kernel.org, damon@lists.linux.dev,
mkoutny@suse.com
Subject: Re: [PATCH v5 24/36] mm/mempolicy: add in-kernel MPOL_BIND interfaces for drivers/services
Date: Tue, 21 Jul 2026 18:36:37 +0000 [thread overview]
Message-ID: <20260721183638.200901F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260720193431.3841992-25-gourry@gourry.net>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] `mpol_bind_node()` and `mpol_private_bind()` fail to validate `nid` against bounds, leading to stack buffer overflows and out-of-bounds reads.
- [Medium] `__mpol_bind_node()` calls `mpol_set_nodemask()` without holding `task_lock(current)` or `mmap_lock`, causing a data race and potential torn read.
- [Medium] `mpol_bind_node()` unconditionally rejects private node bindings, breaking the documented API contract.
--
--- Patch [24]: [PATCH v5 24/36] mm/mempolicy: add in-kernel MPOL_BIND interfaces for drivers/services ---
commit 056427d8f98ec56375b0a715f69798d4dfde2ec3
Author: Gregory Price <gourry@gourry.net>
mm/mempolicy: add in-kernel MPOL_BIND interfaces for drivers/services
This patch adds and exports interfaces to enable modules to build MPOL_BIND
mempolicies pinned to a private NUMA node. It exports mpol_bind_node() and
mpol_private_bind() for module use, widens the __mpol_put() export, and
adjusts mpol_set_nodemask() to handle MPOL_F_PRIVATE flags.
> diff --git a/mm/mempolicy.c b/mm/mempolicy.c
> index e83c2c7a94c1d..a3ffb09897489 100644
> --- a/mm/mempolicy.c
> +++ b/mm/mempolicy.c
> @@ -432,6 +432,18 @@ static int mpol_set_nodemask(struct mempolicy *pol,
> else
> pol->w.cpuset_mems_allowed = cpuset_current_mems_allowed;
>
> + /*
> + * Private nodes are not in cpuset.mems, so they're always stripped.
> + * Driver-allocated policies will already have MPOL_F_PRIVATE set,
> + * if that's the case, add back in the requested set of private nodes.
> + */
> + for_each_node_mask(nid, *nodes) {
> + if (!node_is_private(nid))
> + continue;
> + if (pol->flags & MPOL_F_PRIVATE)
> + node_set(nid, nsc->mask2);
> + }
[Severity: Medium]
The commit message mentions that N_MEMORY_PRIVATE node bindings are honored
if the node has CAP_USER_NUMA. Does this implementation actually perform that
capability check?
It looks like this only checks for MPOL_F_PRIVATE. If mpol_bind_node() calls
__mpol_bind_node() with flags=0, wouldn't the private node be stripped
unconditionally, causing the nodemask to become empty and returning -EINVAL?
[ ... ]
> +static struct mempolicy *__mpol_bind_node(int nid, unsigned short flags)
> +{
> + struct mempolicy *pol;
> + nodemask_t nodes;
> + int err;
> +
> + NODEMASK_SCRATCH(scratch);
> +
> + if (!scratch)
> + return ERR_PTR(-ENOMEM);
> +
> + nodes_clear(nodes);
> + node_set(nid, nodes);
[Severity: High]
Should nid be validated against MAX_NUMNODES before being used?
If an invalid or unsanitized node ID like NUMA_NO_NODE (-1) or a value
greater than MAX_NUMNODES is passed from a module, could node_set()
perform an out-of-bounds write on the stack-allocated nodemask_t?
> +
> + pol = mpol_new(MPOL_BIND, flags, &nodes);
> + if (IS_ERR(pol)) {
> + NODEMASK_SCRATCH_FREE(scratch);
> + return pol;
> + }
> +
> + err = mpol_set_nodemask(pol, &nodes, scratch);
[Severity: Medium]
Does this call to mpol_set_nodemask() need to hold task_lock(current) or
mmap_lock?
mpol_set_nodemask() reads cpuset_current_mems_allowed (current->mems_allowed).
Without locking, couldn't this race with concurrent cpuset updates and result
in a torn read or corrupted mempolicy nodemask?
> + NODEMASK_SCRATCH_FREE(scratch);
> + if (err) {
> + mpol_put(pol);
> + return ERR_PTR(err);
> + }
> + return pol;
> +}
> +
> +/**
> + * mpol_private_bind - build an MPOL_BIND policy pinned to a private node
> + * @nid: an N_MEMORY_PRIVATE node
> + *
> + * Returns a refcounted mempolicy that binds allocations to @nid with the
> + * private-placement intent (MPOL_F_PRIVATE). This binds to @nid regardless
> + * of the node's CAP_USER_NUMA, providing a privileged way for node-owners
> + * to bind driver/service owned VMAs to the node.
> + *
> + * Like any MPOL_BIND it is relaxable: an unsatisfiable request falls back
> + * rather than failing.
> + *
> + * Must be called while @nid is N_MEMORY_PRIVATE.
> + *
> + * The caller owns the reference and frees it with mpol_put().
> + *
> + * Return: the policy, or an ERR_PTR on failure.
> + */
> +struct mempolicy *mpol_private_bind(int nid)
> +{
> + if (!node_is_private(nid))
[Severity: High]
Similar to the issue in __mpol_bind_node(), if an invalid nid is passed in,
could node_is_private() read out of bounds?
> + return ERR_PTR(-EINVAL);
> + return __mpol_bind_node(nid, MPOL_F_PRIVATE);
> +}
> +EXPORT_SYMBOL_FOR_MODULES(mpol_private_bind, "kmem");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720193431.3841992-1-gourry@gourry.net?part=24
next prev parent reply other threads:[~2026-07-21 18:36 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 19:33 [PATCH v5 00/36] Private Memory NUMA Nodes Gregory Price
2026-07-20 19:33 ` [PATCH v5 01/36] mm: refactor find_next_best_node to find_next_best_node_in Gregory Price
2026-07-21 5:46 ` Balbir Singh
2026-07-20 19:33 ` [PATCH v5 02/36] mm/page_alloc: refactor build_node_zonelist() out of build_zonelists() Gregory Price
2026-07-20 19:33 ` [PATCH v5 03/36] mm/page_alloc: let the bulk and folio allocators carry alloc_flags Gregory Price
2026-07-21 18:26 ` sashiko-bot
2026-07-20 19:33 ` [PATCH v5 04/36] numa: introduce N_MEMORY_PRIVATE Gregory Price
2026-07-21 18:18 ` sashiko-bot
2026-07-20 19:33 ` [PATCH v5 05/36] mm: add ZONELIST_PRIVATE(_NOFALLBACK) for N_MEMORY_PRIVATE nodes Gregory Price
2026-07-20 19:34 ` [PATCH v5 06/36] cpuset: exclude private nodes from cpuset.mems (default-open) Gregory Price
2026-07-21 18:22 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 07/36] mm/memory_hotplug: disallow migration-driven private node hotunplug Gregory Price
2026-07-20 19:34 ` [PATCH v5 08/36] mm/mempolicy: skip private node folios when queueing for migration Gregory Price
2026-07-21 18:22 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 09/36] mm/migrate: disallow userland driven migration for private nodes Gregory Price
2026-07-21 18:32 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 10/36] mm/madvise: disallow madvise operations on private node folios Gregory Price
2026-07-21 18:30 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 11/36] mm/compaction: disallow compaction on private nodes Gregory Price
2026-07-21 18:22 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 12/36] mm/page_alloc: clear private node watermarks and system reserves Gregory Price
2026-07-20 19:34 ` [PATCH v5 13/36] mm/mempolicy: disallow NUMA Balancing prot_none on private nodes Gregory Price
2026-07-20 19:34 ` [PATCH v5 14/36] mm/damon: skip private node memory in DAMON migration and pageout Gregory Price
2026-07-21 18:18 ` sashiko-bot
2026-07-21 23:46 ` SJ Park
2026-07-20 19:34 ` [PATCH v5 15/36] mm/ksm: skip KSM for managed-memory folios Gregory Price
2026-07-20 19:34 ` [PATCH v5 16/36] mm/khugepaged: skip private node folios when trying to collapse Gregory Price
2026-07-21 18:36 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 17/36] mm/vmscan: disallow reclaim of private node memory Gregory Price
2026-07-21 18:35 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 18/36] mm/gup: disallow longterm pin of private node folios Gregory Price
2026-07-20 19:34 ` [PATCH v5 19/36] proc: include N_MEMORY_PRIVATE nodes in numa_maps output Gregory Price
2026-07-21 18:30 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 20/36] mm/memcontrol: account private-node memory in per-node stats Gregory Price
2026-07-21 18:33 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 21/36] proc/kcore: include private-node RAM in the kcore RAM map Gregory Price
2026-07-20 20:05 ` Omar Sandoval
2026-07-20 19:34 ` [PATCH v5 22/36] mm/mempolicy: add MPOL_F_PRIVATE and zonelist selection Gregory Price
2026-07-21 19:28 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 23/36] mm/mempolicy: apply policy at the kernel zone for private-node binds Gregory Price
2026-07-21 19:39 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 24/36] mm/mempolicy: add in-kernel MPOL_BIND interfaces for drivers/services Gregory Price
2026-07-21 18:36 ` sashiko-bot [this message]
2026-07-20 19:34 ` [PATCH v5 25/36] mm/memory_hotplug: support N_MEMORY_PRIVATE node hotplug Gregory Price
2026-07-21 18:33 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 26/36] mm: add NODE_PRIVATE_CAP_RECLAIM for opted-in private node reclaim Gregory Price
2026-07-21 20:02 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 27/36] mm: add NODE_PRIVATE_CAP_USER_NUMA for userland numa controls Gregory Price
2026-07-21 20:13 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 28/36] mm: add NODE_PRIVATE_CAP_HOTUNPLUG for opted-in private nodes Gregory Price
2026-07-20 19:34 ` [PATCH v5 29/36] mm: add NODE_PRIVATE_CAP_DEMOTION for private-node tiering demotion Gregory Price
2026-07-21 20:28 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 30/36] mm: add NODE_PRIVATE_CAP_NUMA_BALANCING for private-node NUMA balancing Gregory Price
2026-07-20 19:34 ` [PATCH v5 31/36] mm: add NODE_PRIVATE_CAP_LTPIN for private node folio pinning Gregory Price
2026-07-20 19:34 ` [PATCH v5 32/36] mm/khugepaged: base private node collapse eligiblity on actor/cap bits Gregory Price
2026-07-21 20:49 ` sashiko-bot
2026-07-20 19:34 ` [PATCH v5 33/36] Documentation/mm: describe private (N_MEMORY_PRIVATE) memory nodes Gregory Price
2026-07-20 19:34 ` [PATCH v5 34/36] mm/mempolicy: add mpol_set_shared_policy_range() Gregory Price
2026-07-20 19:34 ` [PATCH v5 35/36] KVM: guest_memfd: bind backing memory to a NUMA node at creation Gregory Price
2026-07-21 21:11 ` sashiko-bot
2026-07-21 3:46 ` [PATCH v5 00/36] Private Memory NUMA Nodes Balbir Singh
2026-07-21 18:16 ` Gregory Price
2026-07-21 13:26 ` Zenghui Yu
2026-07-21 17:18 ` Gregory Price
2026-07-21 18:06 ` [PATCH v5 36/36] KVM: selftests: add a guest_memfd FLAG_BIND_NODE test Gregory Price
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260721183638.200901F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=damon@lists.linux.dev \
--cc=gourry@gourry.net \
--cc=hannes@cmpxchg.org \
--cc=kvm@vger.kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=mkoutny@suse.com \
--cc=nvdimm@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.