Thread (61 messages) 61 messages, 8 authors, 2025-09-03

Re: [PATCH v6 mm-new 03/10] mm: thp: add a new kfunc bpf_mm_get_task()

From: Lorenzo Stoakes <hidden>
Date: 2025-08-29 10:44:05
Also in: bpf, linux-mm

On Thu, Aug 28, 2025 at 02:47:34PM +0800, Yafang Shao wrote:
On Wed, Aug 27, 2025 at 11:42 PM Lorenzo Stoakes
[off-list ref] wrote:
quoted
On Tue, Aug 26, 2025 at 03:19:41PM +0800, Yafang Shao wrote:
quoted
We will utilize this new kfunc bpf_mm_get_task() to retrieve the
associated task_struct from the given @mm. The obtained task_struct must
be released by calling bpf_task_release() as a paired operation.
You're basically describing the patch you're not saying why - yeah you're
getting a task struct from an mm (only if CONFIG_MEMCG which you don't
mention here), but not for what purpose you intend to use this?
For example, we could retrieve task->comm or other attributes and make
decisions based on that information. I’ll provide a clearer
description in the next revision.
Thanks!
quoted
quoted
Signed-off-by: Yafang Shao <redacted>
---
 mm/bpf_thp.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
diff --git a/mm/bpf_thp.c b/mm/bpf_thp.c
index b757e8f425fd..46b3bc96359e 100644
--- a/mm/bpf_thp.c
+++ b/mm/bpf_thp.c
@@ -205,11 +205,45 @@ __bpf_kfunc void bpf_put_mem_cgroup(struct mem_cgroup *memcg)
 #endif
 }

+/**
+ * bpf_mm_get_task - Get the task struct associated with a mm_struct.
+ * @mm: The mm_struct to query
+ *
+ * The obtained task_struct must be released by calling bpf_task_release().
Hmmm so now bpf programs can cause kernel bugs by keeping a reference around?

This feels extremely dodgy, I don't like this at all.

I thought the whole point of BPF was that this kind of thing couldn't possibly
happen?

Or would this be a kernel bug?

If a bpf program can lead to a refcount not being put, this is not
upstreamable surely?
As explained by Andrii, the BPF verifier can protect it.
Yeah that's nice!
quoted
quoted
+ *
+ * Return: The associated task_struct on success, or NULL on failure. Note that
+ * this function depends on CONFIG_MEMCG being enabled - it will always return
+ * NULL if CONFIG_MEMCG is not configured.
+ */
+__bpf_kfunc struct task_struct *bpf_mm_get_task(struct mm_struct *mm)
+{
+#ifdef CONFIG_MEMCG
+     struct task_struct *task;
+
+     if (!mm)
+             return NULL;
+     rcu_read_lock();
+     task = rcu_dereference(mm->owner);
quoted
+     if (!task)
+             goto out;
+     if (!refcount_inc_not_zero(&task->rcu_users))
+             goto out;
+
+     rcu_read_unlock();
+     return task;
+
+out:
+     rcu_read_unlock();
+#endif
This #ifdeffery is horrid, can we please just have separate functions instead of
inside the one? Thanks.
quoted
+     return NULL;
So we can't tell the difference between this failling due to CONFIG_MEMCG
not being set (in which case it will _always_ fail) or we couldn't get a
task or we couldn't get a refcount on the task.

Maybe this doesn't matter since perhaps we are only using this if
CONFIG_MEMCG but in that case why even expose this if !CONFIG_MEMCG?
As suggested by Andrii, I will remove this kfunc and mark mm->owner as
BTF_TYPE_SAFE_TRUSTED_OR_NULL.
OK thanks!
Thanks for your comments.
You're welcome :)
--
Regards
Yafang
Cheers, Lorenzo
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help