mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Amery Hung <ameryhung@gmail.com>
To: Pu Lehui <pulehui@huaweicloud.com>,
	bpf@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Yonghong Song <yonghong.song@linux.dev>,
	Song Liu <song@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	Pu Lehui <pulehui@huawei.com>
Subject: Re: [PATCH bpf v4 2/4] bpf: Fix UAF due to missing link type check in mprog
Date: Mon, 20 Jul 2026 11:44:33 -0700	[thread overview]
Message-ID: <4b343a35-45a2-40c2-a27d-36998688f5d7@gmail.com> (raw)
In-Reply-To: <20260720134547.1289964-3-pulehui@huaweicloud.com>



On 7/20/26 6:45 AM, Pu Lehui wrote:
> From: Pu Lehui <pulehui@huawei.com>
> 
> In bpf_mprog_link, the code does not check the link->type first before
> dereferencing link->prog->type. This missing validation allows a user to
> pass an abnormal non-netkit or non-tcx link via relative_fd. If do
> BPF_LINK_UPDATE on the abnormal link, it can trigger a UAF issue.
> 
> CPU0                                      CPU1
> netkit_link_prog_attach
> bpf_mprog_attach
> bpf_mprog_tuple_relative
> bpf_mprog_link
>    link = bpf_link_get_from_fd(id_or_fd);
>                                            BPF_LINK_UPDATE
>                                            ...
>                                            old_prog = xchg(&link->link.prog, new_prog);
>                                            bpf_prog_put(old_prog);
>    if (type && link->prog->type != type) <-- trigger UAF
> 
> Fix this by strictly validate link->type in bpf_mprog_link against the
> expected link type. bpf_mprog_tuple_relative is also adjusted to accept
> and pass down the expected link type.
> 
> Fixes: 053c8e1f235d ("bpf: Add generic attach/detach/query API for multi-progs")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Signed-off-by: Pu Lehui <pulehui@huawei.com>

Reviewed-by: Amery Hung <ameryhung@gmail.com>

The message can be improved. The reason for the UAF is that each 
subsystem provides its own protection for link->prog. Since there is no 
cross subsystem protection (if not considering the RCU of prog tear 
down), dereferencing the prog of an anchor link that does not belong to 
the current subsystem is not safe: it may have been freed. Therefore, we
need to validate link->type to reject foreign anchors.

There are also some grammar errors:
If do -> If doing
strictly validate -> strictly validating.

> ---
>   kernel/bpf/mprog.c | 15 ++++++++++-----
>   1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/bpf/mprog.c b/kernel/bpf/mprog.c
> index 1394168062e8..367f8f10da0a 100644
> --- a/kernel/bpf/mprog.c
> +++ b/kernel/bpf/mprog.c
> @@ -6,7 +6,7 @@
>   
>   static int bpf_mprog_link(struct bpf_tuple *tuple,
>   			  u32 id_or_fd, u32 flags,
> -			  enum bpf_prog_type type)
> +			  enum bpf_link_type type)
>   {
>   	struct bpf_link *link = ERR_PTR(-EINVAL);
>   	bool id = flags & BPF_F_ID;
> @@ -17,7 +17,7 @@ static int bpf_mprog_link(struct bpf_tuple *tuple,
>   		link = bpf_link_get_from_fd(id_or_fd);
>   	if (IS_ERR(link))
>   		return PTR_ERR(link);
> -	if (type && link->prog->type != type) {
> +	if (type && link->type != type) {
>   		bpf_link_put(link);
>   		return -EINVAL;
>   	}
> @@ -52,21 +52,22 @@ static int bpf_mprog_prog(struct bpf_tuple *tuple,
>   
>   static int bpf_mprog_tuple_relative(struct bpf_tuple *tuple,
>   				    u32 id_or_fd, u32 flags,
> -				    enum bpf_prog_type type)
> +				    enum bpf_link_type ltype,
> +				    enum bpf_prog_type ptype)
>   {
>   	bool link = flags & BPF_F_LINK;
>   	bool id = flags & BPF_F_ID;
>   
>   	memset(tuple, 0, sizeof(*tuple));
>   	if (link)
> -		return bpf_mprog_link(tuple, id_or_fd, flags, type);
> +		return bpf_mprog_link(tuple, id_or_fd, flags, ltype);
>   	/* If no relevant flag is set and no id_or_fd was passed, then
>   	 * tuple link/prog is just NULLed. This is the case when before/
>   	 * after selects first/last position without passing fd.
>   	 */
>   	if (!id && !id_or_fd)
>   		return 0;
> -	return bpf_mprog_prog(tuple, id_or_fd, flags, type);
> +	return bpf_mprog_prog(tuple, id_or_fd, flags, ptype);
>   }
>   
>   static void bpf_mprog_tuple_put(struct bpf_tuple *tuple)
> @@ -243,6 +244,8 @@ int bpf_mprog_attach(struct bpf_mprog_entry *entry,
>   		return -EEXIST;
>   	ret = bpf_mprog_tuple_relative(&rtuple, id_or_fd,
>   				       flags & ~BPF_F_REPLACE,
> +				       link ? link->type :
> +				       BPF_LINK_TYPE_UNSPEC,

nit: keep it in a line. It is well under 100 cols.

>   				       prog_new->type);
>   	if (ret)
>   		return ret;
> @@ -343,6 +346,8 @@ int bpf_mprog_detach(struct bpf_mprog_entry *entry,
>   	if (!bpf_mprog_total(entry))
>   		return -ENOENT;
>   	ret = bpf_mprog_tuple_relative(&rtuple, id_or_fd, flags,
> +				       link ? link->type :
> +				       BPF_LINK_TYPE_UNSPEC,

Same here.

>   				       prog ? prog->type :
>   				       BPF_PROG_TYPE_UNSPEC);
>   	if (ret)


  reply	other threads:[~2026-07-20 18:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-20 13:45 [PATCH bpf v4 0/4] Fixes for bpf link update Pu Lehui
2026-07-20 13:45 ` [PATCH bpf v4 1/4] bpf: Fix potential UAF in bpf_netns_link_update_prog Pu Lehui
2026-07-20 17:33   ` Amery Hung
2026-07-20 13:45 ` [PATCH bpf v4 2/4] bpf: Fix UAF due to missing link type check in mprog Pu Lehui
2026-07-20 18:44   ` Amery Hung [this message]
2026-07-21  3:39     ` Pu Lehui
2026-07-20 13:45 ` [PATCH bpf v4 3/4] bpf: Fix potential UAF when reading bpf link info Pu Lehui
2026-07-20 14:16   ` Mykyta Yatsenko
2026-07-21  3:38     ` Pu Lehui
2026-07-20 13:45 ` [PATCH bpf v4 4/4] bpf, cgroup: Fix storage null-ptr-deref after replacing prog Pu Lehui
2026-07-20 18:58   ` Amery Hung

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=4b343a35-45a2-40c2-a27d-36998688f5d7@gmail.com \
    --to=ameryhung@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=pulehui@huawei.com \
    --cc=pulehui@huaweicloud.com \
    --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

Powered by JetHome