BPF List
 help / color / mirror / Atom feed
From: Matt Bobrowski <mattbobrowski@google.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, kpsingh@google.com,
	jannh@google.com, jolsa@kernel.org, daniel@iogearbox.net,
	brauner@kernel.org, torvalds@linux-foundation.org,
	linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 bpf-next 2/9] bpf: add new acquire/release BPF kfuncs for mm_struct
Date: Wed, 6 Mar 2024 07:39:31 +0000	[thread overview]
Message-ID: <eb9fb133d5611d40ab1f073cc2fcaa48cb581998.1709675979.git.mattbobrowski@google.com> (raw)
In-Reply-To: <cover.1709675979.git.mattbobrowski@google.com>

A BPF LSM program will at times introspect the mm_struct that is
nested within a given task_struct. Such introspection performed by a
BPF LSM program may involve reading virtual addresses out from fields
like arg_start/arg_end and env_start/env_end, or reading fields
directly out from the backing exe_file. In order to perform reliable
reads against fields contained within mm_struct, we need to introduce
a new set of BPF kfuncs that have the ability to acquire and release
references on the mm_struct that is nested within a task_struct.

The following BPF kfuncs have been added in order to support this
capability:

struct mm_struct *bpf_task_mm_grab(struct task_struct *task);
void bpf_mm_drop(struct mm_struct *mm);

These new BPF kfuncs are pretty self-explanatory, but in kernel terms
bpf_task_mm_grab() effectively allows you to get a reference on the
mm_struct nested within a supplied task_struct. Whereas, bpf_mm_drop()
allows you put a reference on a previously gotten mm_struct
reference. Both BPF kfuncs are also backed by BPF's respective
KF_ACQUIRE/KF_RELEASE semantics, ensuring that the BPF program behaves
in accordance to the constraints enforced upon it when operating on
reference counted in-kernel data structures.

Notably, these newly added BPF kfuncs are simple wrappers around the
mmgrab() and mmdrop() in-kernel helpers. Both mmgrab() and mmdrop()
are used in favour of their somewhat similar counterparts mmget() and
mmput() as they're considered to be the more lightweight variants in
comparison, and there's no requirement to also pin the underlying
address spaces just yet.

Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
---
 kernel/trace/bpf_trace.c | 47 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index f639663ac339..801808b6efb0 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1473,10 +1473,57 @@ __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str,
 	return __vfs_getxattr(dentry, dentry->d_inode, name__str, value, value_len);
 }
 
+/**
+ * bpf_task_mm_grab - get a reference on the mm_struct nested within the
+ * 		      supplied task_struct
+ * @task: task_struct nesting the mm_struct that is to be referenced
+ *
+ * Grab a reference on the mm_struct that is nested within the supplied
+ * *task*. This kfunc will return NULL for threads that do not possess a valid
+ * mm_struct. For example, those that are flagged as PF_KTHREAD. A reference on
+ * a mm_struct acquired by this kfunc must be released using bpf_mm_drop().
+ *
+ * This helper only pins the mm_struct and not necessarily the address space
+ * associated with the referenced mm_struct that is returned from this
+ * kfunc. Internally, this kfunc leans on mmgrab(), such that calling
+ * bpf_task_mm_grab() would be analogous to calling mmgrab() outside of BPF
+ * program context.
+ *
+ * Return: A referenced pointer to the mm_struct nested within the supplied
+ * *task*, or NULL.
+ */
+__bpf_kfunc struct mm_struct *bpf_task_mm_grab(struct task_struct *task)
+{
+	struct mm_struct *mm;
+
+	task_lock(task);
+	mm = task->mm;
+	if (likely(mm))
+		mmgrab(mm);
+	task_unlock(task);
+
+	return mm;
+}
+
+/**
+ * bpf_mm_drop - put a reference on the supplied mm_struct
+ * @mm: mm_struct of which to put a reference on
+ *
+ * Put a reference on the supplied *mm*. This kfunc internally leans on
+ * mmdrop(), such that calling bpf_mm_drop() would be analogous to calling
+ * mmdrop() outside of BPF program context.
+ */
+__bpf_kfunc void bpf_mm_drop(struct mm_struct *mm)
+{
+	mmdrop(mm);
+}
+
 __bpf_kfunc_end_defs();
 
 BTF_KFUNCS_START(lsm_kfunc_set_ids)
 BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS)
+BTF_ID_FLAGS(func, bpf_task_mm_grab, KF_ACQUIRE | KF_TRUSTED_ARGS | KF_RET_NULL);
+BTF_ID_FLAGS(func, bpf_mm_drop, KF_RELEASE);
 BTF_KFUNCS_END(lsm_kfunc_set_ids)
 
 static int bpf_lsm_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
-- 
2.44.0.278.ge034bb2e1d-goog

/M

  parent reply	other threads:[~2024-03-06  7:39 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-06  7:39 [PATCH v2 bpf-next 0/9] add new acquire/release BPF kfuncs Matt Bobrowski
2024-03-06  7:39 ` [PATCH v2 bpf-next 1/9] bpf: rename fs_kfunc_set_ids to lsm_kfunc_set_ids Matt Bobrowski
2024-03-06  7:39 ` Matt Bobrowski [this message]
2024-03-06 11:50   ` [PATCH v2 bpf-next 2/9] bpf: add new acquire/release BPF kfuncs for mm_struct Christian Brauner
2024-03-06  7:39 ` [PATCH v2 bpf-next 3/9] bpf/selftests: add selftests for mm_struct acquire/release BPF kfuncs Matt Bobrowski
2024-03-06  7:40 ` [PATCH v2 bpf-next 4/9] bpf: add new acquire/release based BPF kfuncs for exe_file Matt Bobrowski
2024-03-06 11:31   ` Christian Brauner
2024-03-06  7:40 ` [PATCH v2 bpf-next 5/9] bpf/selftests: add selftests for exe_file acquire/release BPF kfuncs Matt Bobrowski
2024-03-06  7:40 ` [PATCH v2 bpf-next 6/9] bpf: add acquire/release based BPF kfuncs for fs_struct's paths Matt Bobrowski
2024-03-06 11:47   ` Christian Brauner
2024-03-06  7:40 ` [PATCH v2 bpf-next 7/9] bpf/selftests: add selftests for root/pwd path based BPF kfuncs Matt Bobrowski
2024-03-06  7:40 ` [PATCH v2 bpf-next 9/9] bpf/selftests: adapt selftests test_d_path for BPF kfunc bpf_path_d_path() Matt Bobrowski
2024-03-06  7:40 ` [PATCH v2 bpf-next 8/9] bpf: add trusted d_path() based " Matt Bobrowski
2024-03-06 11:21 ` [PATCH v2 bpf-next 0/9] add new acquire/release BPF kfuncs Christian Brauner
2024-03-06 12:13   ` Christian Brauner
2024-03-06 21:44     ` Paul Moore
2024-03-07  4:05     ` Alexei Starovoitov
2024-03-07  9:54       ` Christian Brauner
2024-03-07 20:50         ` Paul Moore
2024-03-08  3:25           ` Alexei Starovoitov
2024-03-08 10:58             ` Christian Brauner
2024-03-08  3:11         ` Alexei Starovoitov
2024-03-08 10:35           ` Christian Brauner
2024-03-09  1:23             ` Alexei Starovoitov
2024-03-11 12:00               ` Christian Brauner
2024-03-12 17:06                 ` Matt Bobrowski
2024-03-12 20:11                   ` Matt Bobrowski
2024-03-18 13:24                   ` Christian Brauner
2024-03-13 21:05                 ` Alexei Starovoitov
2024-03-18 13:14                   ` Christian Brauner
2024-03-27 21:41                     ` Alexei Starovoitov

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=eb9fb133d5611d40ab1f073cc2fcaa48cb581998.1709675979.git.mattbobrowski@google.com \
    --to=mattbobrowski@google.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=jannh@google.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@google.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=torvalds@linux-foundation.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox