[PATCH bpf-next v6 4/5] bpf: Mark linux_binprm->mm as trusted-or-null

From: Anastasios Papagiannis

Date: Tue Sep 08 2026 - 10:27:33 EST


Mark linux_binprm->mm as a trusted-or-null nested pointer so BPF programs
can pass it to kfuncs after a NULL check.

The field is either NULL or points to a live mm_struct whenever BPF can
access a linux_binprm. On successful exec, exec_mmap() installs the new
address space before begin_new_exec() clears bprm->mm. The bprm_mm_init()
error path clears the field before mmdrop(), and free_bprm() clears it
before mmput(), as ensured by an earlier patch in this series.

Update the existing LSM selftest to check bprm->mm for NULL before
dereferencing it, as required for trusted-or-null pointers.

Signed-off-by: Anastasios Papagiannis <tasos.papagiannnis@xxxxxxxxx>
Reviewed-by: Sun Jian <sun.jian.kdev@xxxxxxxxx>
Reviewed-By: Matt Bobrowski <matt@xxxxxxxxxxxxx>
---
kernel/bpf/verifier.c | 5 +++++
tools/testing/selftests/bpf/progs/lsm.c | 5 ++++-
2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9e79750e2480..791b3d25caa5 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6004,6 +6004,10 @@ BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct dentry) {
struct inode *d_inode;
};

+BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct linux_binprm) {
+ struct mm_struct *mm;
+};
+
BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket) {
struct sock *sk;
};
@@ -6058,6 +6062,7 @@ static bool type_is_trusted_or_null(struct bpf_verifier_env *env,
{
BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct socket));
BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct dentry));
+ BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct linux_binprm));
BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct vm_area_struct));

return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id,
diff --git a/tools/testing/selftests/bpf/progs/lsm.c b/tools/testing/selftests/bpf/progs/lsm.c
index 7de173daf27b..7441d66c080c 100644
--- a/tools/testing/selftests/bpf/progs/lsm.c
+++ b/tools/testing/selftests/bpf/progs/lsm.c
@@ -113,6 +113,7 @@ int BPF_PROG(test_void_hook, struct linux_binprm *bprm)
{
__u32 pid = bpf_get_current_pid_tgid() >> 32;
struct inner_map *inner_map;
+ struct mm_struct *mm;
char args[64];
__u32 key = 0;
__u64 *value;
@@ -121,7 +122,9 @@ int BPF_PROG(test_void_hook, struct linux_binprm *bprm)
bprm_count++;

bpf_copy_from_user(args, sizeof(args), (void *)bprm->vma->vm_mm->arg_start);
- bpf_copy_from_user(args, sizeof(args), (void *)bprm->mm->arg_start);
+ mm = bprm->mm;
+ if (mm)
+ bpf_copy_from_user(args, sizeof(args), (void *)mm->arg_start);

value = bpf_map_lookup_elem(&array, &key);
if (value)
--
2.55.0