From: Matt Bobrowski <mattbobrowski@google.com>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
ohn Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@fomichev.me>,
Josh Don <joshdon@google.com>, Jiri Olsa <jolsa@kernel.org>,
Kaiyan Mei <M202472210@hust.edu.cn>,
Yinhao Hu <dddddd@hust.edu.cn>, Dongliang Mu <dzm91@hust.edu.cn>
Subject: Re: [PATCH bpf-next 1/2] bpf: annotate file argument as __nullable in bpf_lsm_mmap_file
Date: Wed, 10 Dec 2025 10:06:27 +0000 [thread overview]
Message-ID: <aTlGIygVuQSLcNwN@google.com> (raw)
In-Reply-To: <20251210090701.2753545-1-mattbobrowski@google.com>
On Wed, Dec 10, 2025 at 09:07:00AM +0000, Matt Bobrowski wrote:
> As reported in [0], anonymous memory mappings are not backed by a
> struct file instance. Consequently, the struct file pointer passed to
> the security_mmap_file() LSM hook is NULL in such cases.
>
> The BPF verifier is currently unaware of this, allowing BPF LSM
> programs to dereference this struct file pointer without needing to
> perform an explicit NULL check. This leads to potential NULL pointer
> dereference and a kernel crash.
>
> Add a strong override for bpf_lsm_mmap_file() which annotates the
> struct file pointer parameter with the __nullable suffix. This
> explicitly informs the BPF verifier that this pointer (PTR_MAYBE_NULL)
> can be NULL, forcing BPF LSM programs to perform a check on it before
> dereferencing it.
>
> [0] https://lore.kernel.org/bpf/5e460d3c.4c3e9.19adde547d8.Coremail.kaiyanm@hust.edu.cn/
>
> Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
> Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
> Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
> Closes: https://lore.kernel.org/bpf/5e460d3c.4c3e9.19adde547d8.Coremail.kaiyanm@hust.edu.cn/
> Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
> ---
> MAINTAINERS | 1 +
> kernel/bpf/Makefile | 12 +++++++++++-
> kernel/bpf/bpf_lsm.c | 5 +++--
> kernel/bpf/bpf_lsm_proto.c | 20 ++++++++++++++++++++
> 4 files changed, 35 insertions(+), 3 deletions(-)
> create mode 100644 kernel/bpf/bpf_lsm_proto.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index e36689cd7cc7..c531fae0dc06 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4754,6 +4754,7 @@ S: Maintained
> F: Documentation/bpf/prog_lsm.rst
> F: include/linux/bpf_lsm.h
> F: kernel/bpf/bpf_lsm.c
> +F: kernel/bpf/bpf_lsm_proto.c
> F: kernel/trace/bpf_trace.c
> F: security/bpf/
>
> diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
> index 232cbc97434d..79cf22860a99 100644
> --- a/kernel/bpf/Makefile
> +++ b/kernel/bpf/Makefile
> @@ -42,7 +42,17 @@ endif
> ifeq ($(CONFIG_BPF_JIT),y)
> obj-$(CONFIG_BPF_SYSCALL) += bpf_struct_ops.o
> obj-$(CONFIG_BPF_SYSCALL) += cpumask.o
> -obj-${CONFIG_BPF_LSM} += bpf_lsm.o
> +# bpf_lsm_proto.o must precede bpf_lsm.o. The current pahole logic
> +# deduplicates function prototypes within
> +# btf_encoder__add_saved_func() by keeping the first instance seen. We
> +# need the function prototype(s) in bpf_lsm_proto.o to take precedence
> +# over those within bpf_lsm.o. Having bpf_lsm_proto.o precede
> +# bpf_lsm.o ensures its DWARF CU is processed early, forcing the
> +# generated BTF to contain the overrides.
> +#
> +# Notably, this is a temporary workaround whilst the deduplication
> +# semantics within pahole are revisited accordingly.
> +obj-${CONFIG_BPF_LSM} += bpf_lsm_proto.o bpf_lsm.o
> endif
> ifneq ($(CONFIG_CRYPTO),)
> obj-$(CONFIG_BPF_SYSCALL) += crypto.o
> diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
> index 7cb6e8d4282c..0c4a0c8e6f70 100644
> --- a/kernel/bpf/bpf_lsm.c
> +++ b/kernel/bpf/bpf_lsm.c
> @@ -18,10 +18,11 @@
> #include <linux/bpf-cgroup.h>
>
> /* For every LSM hook that allows attachment of BPF programs, declare a nop
> - * function where a BPF program can be attached.
> + * function where a BPF program can be attached. Notably, we qualify each with
> + * weak linkage such that strong overrides can be implemented if need be.
> */
> #define LSM_HOOK(RET, DEFAULT, NAME, ...) \
> -noinline RET bpf_lsm_##NAME(__VA_ARGS__) \
> +__weak noinline RET bpf_lsm_##NAME(__VA_ARGS__) \
> { \
> return DEFAULT; \
> }
> diff --git a/kernel/bpf/bpf_lsm_proto.c b/kernel/bpf/bpf_lsm_proto.c
> new file mode 100644
> index 000000000000..273bc7ddad64
> --- /dev/null
> +++ b/kernel/bpf/bpf_lsm_proto.c
> @@ -0,0 +1,20 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2025 Google LLC.
> + */
> +
> +#include <linux/fs.h>
> +#include <linux/bpf_lsm.h>
> +
> +/*
> + * A strong definition for BPF LSM hook mmap_file(). Differs from its weak
> + * definition counterpart only through its of the __nullable suffix on its
> + * struct file pointer parameter. Annotating with a __nullable suffix allows the
> + * BPF verifier to enforce stricter NULL pointer checking in cases where a BPF
> + * program is attempting to access the BPF program context.
> + */
Ah, I just realized that I need to fix up the wording within this
comment. I'll do that when I send out v2.
> +int bpf_lsm_mmap_file(struct file *file__nullable, unsigned long reqprot,
> + unsigned long prot, unsigned long flags)
> +{
> + return 0;
> +}
> --
> 2.52.0.223.gf5cc29aaa4-goog
>
prev parent reply other threads:[~2025-12-10 10:06 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-10 9:07 [PATCH bpf-next 1/2] bpf: annotate file argument as __nullable in bpf_lsm_mmap_file Matt Bobrowski
2025-12-10 9:07 ` [PATCH bpf-next 2/2] selftests/bpf: add test case for BPF LSM hook bpf_lsm_mmap_file Matt Bobrowski
2025-12-10 10:06 ` Matt Bobrowski [this message]
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=aTlGIygVuQSLcNwN@google.com \
--to=mattbobrowski@google.com \
--cc=M202472210@hust.edu.cn \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dddddd@hust.edu.cn \
--cc=dzm91@hust.edu.cn \
--cc=eddyz87@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=joshdon@google.com \
--cc=kpsingh@kernel.org \
--cc=martin.lau@linux.dev \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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