BPF List
 help / color / mirror / Atom feed
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
> 

      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