Skip to content

bpf: prevent offloaded programs from running on host via tcx/netkit#11950

Open
kernel-patches-daemon-bpf[bot] wants to merge 3 commits intobpf_basefrom
series/1085473=>bpf
Open

bpf: prevent offloaded programs from running on host via tcx/netkit#11950
kernel-patches-daemon-bpf[bot] wants to merge 3 commits intobpf_basefrom
series/1085473=>bpf

Conversation

@kernel-patches-daemon-bpf
Copy link
Copy Markdown

Pull request for series with
subject: bpf: prevent offloaded programs from running on host via tcx/netkit
version: 3
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: b5c111f
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

@kernel-patches-review-bot
Copy link
Copy Markdown

commit f286f4b792493a49741f6b2918406a3e4498869c
Author: Jiayuan Chen <jiayuan.chen@linux.dev>

bpf, xdp: move offload check into dev_xdp_install()

bpf_xdp_link_update() calls dev_xdp_install() directly and bypasses
dev_xdp_attach(), so the offload check that lived in dev_xdp_attach()
does not apply. A user can create an XDP link in SKB or native mode
with a regular program and then replace it via BPF_LINK_UPDATE with an
offloaded program, whose bpf_func is bpf_prog_warn_on_exec(), tripping
the WARN on the first packet.

Fixes: 026a4c28e1db3 ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")

> diff --git a/net/core/dev.c b/net/core/dev.c
> index e59f6025067c..8635de70efe7 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -10359,6 +10359,11 @@ static int dev_xdp_install(struct net_device *dev, enum bpf_xdp_mode mode,
>
>  	netdev_ops_assert_locked(dev);
>
> +	if (prog && mode != XDP_MODE_HW && bpf_prog_is_offloaded(prog->aux)) {
> +		NL_SET_ERR_MSG(extack, "Using offloaded program without HW_MODE flag is not supported");
> +		return -EINVAL;
> +	}
> +

While this check addresses offloaded programs (bpf_prog_is_offloaded()),
does it cover device-bound programs? Looking at dev_xdp_attach(), there
are two distinct checks that were in place:

(1) bpf_prog_is_offloaded() check - now moved to dev_xdp_install()
(2) bpf_prog_is_dev_bound() && !bpf_offload_dev_match() check - still in
    dev_xdp_attach()

A program loaded with BPF_F_XDP_DEV_BOUND_ONLY has dev_bound set to true
but offload_requested set to false, meaning bpf_prog_is_offloaded() will
return false. When bpf_xdp_link_update() calls dev_xdp_install() directly,
could such a device-bound program bypass both checks?

If so, this could allow attaching a device-bound program to an SKB-mode
link, potentially causing the generic XDP runner to execute device-specific
kfuncs that cast the generic xdp_md context to driver-specific structures.

Additionally, if the link is in HW mode, the new check evaluates to false
(mode != XDP_MODE_HW) and validation is skipped. Can a program offloaded
to device A be attached via BPF_LINK_UPDATE to an HW link on device B?
If so, the driver might receive XDP_SETUP_PROG_HW and incorrectly cast
the new program's aux->offload->dev_priv to its own internal structure,
resulting in memory corruption.

This concern was raised by sashiko-bot in v2:
https://lore.kernel.org/bpf/20260425104435.ED443C2BCB5@smtp.kernel.org/

>  	if (dev->cfg->hds_config == ETHTOOL_TCP_DATA_SPLIT_ENABLED &&
>  	    prog && !prog->aux->xdp_has_frags) {
>  		NL_SET_ERR_MSG(extack, "unable to install XDP to device using tcp-data-split");
> @@ -10510,10 +10515,6 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
>  			NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
>  			return -EEXIST;
>  		}
> -		if (!offload && bpf_prog_is_offloaded(new_prog->aux)) {
> -			NL_SET_ERR_MSG(extack, "Using offloaded program without HW_MODE flag is not supported");
> -			return -EINVAL;
> -		}
>  		if (bpf_prog_is_dev_bound(new_prog->aux) && !bpf_offload_dev_match(new_prog, dev)) {
>  			NL_SET_ERR_MSG(extack, "Program bound to different device");
>  			return -EINVAL;



AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

In-Reply-To-Subject: bpf, xdp: move offload check into dev_xdp_install()
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/24929498218

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: b5c111f
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: b5c111f
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: 0c7ae13
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: f3b8c28
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

@kernel-patches-daemon-bpf
Copy link
Copy Markdown
Author

Upstream branch: 18fc650
series: https://patchwork.kernel.org/project/netdevbpf/list/?series=1085473
version: 3

mrpre added 2 commits May 8, 2026 13:58
An offloaded prog has its bpf_func replaced by bpf_prog_warn_on_exec()
during bpf_prog_offload_compile(), since it is supposed to run on the
NIC. Both current mprog users, tcx and netkit, dispatch programs via
bpf_prog_run() on the host. Attaching an offloaded prog through any
of their entry points (BPF_PROG_ATTACH, BPF_LINK_CREATE, BPF_LINK_UPDATE
on tcx_*/netkit_*) ends up tripping the WARN on the first packet.

Ideally this validation would live in tcx and netkit, since "must not
be offloaded" is a property of those subsystems' software dispatch,
not of the generic multi-prog attachment layer. However, those two
together have six attach call sites and putting the check in each of
them duplicates the same logic. mprog happens to be the only chokepoint
shared by all of them, so add the check there instead and scope it to
BPF_PROG_TYPE_SCHED_CLS via a small helper, so a future mprog user that
legitimately accepts offloaded programs is not affected.

Use bpf_prog_is_offloaded() rather than bpf_prog_is_dev_bound() +
bpf_offload_dev_match() (as XDP does): bpf_prog_dev_bound_init()
already rejects BPF_F_XDP_DEV_BOUND_ONLY for BPF_PROG_TYPE_SCHED_CLS,
so a dev-bound SCHED_CLS program is always offloaded. The simpler
check is sufficient and also rejects attaching a program offloaded to
device A onto device B.

Fixes: 053c8e1 ("bpf: Add generic attach/detach/query API for multi-progs")
Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
Reported-by: Dongliang Mu <dzm91@hust.edu.cn>
Closes: https://lore.kernel.org/bpf/64d8e2b5-a214-4f3c-b9e8-bcedbcb2c602@hust.edu.cn/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
bpf_xdp_link_update() calls dev_xdp_install() directly and bypasses
dev_xdp_attach(), so the offload check that lived in dev_xdp_attach()
does not apply. A user can create an XDP link in SKB or native mode
with a regular program and then replace it via BPF_LINK_UPDATE with an
offloaded program, whose bpf_func is bpf_prog_warn_on_exec(), tripping
the WARN on the first packet.

Move the check from dev_xdp_attach() into dev_xdp_install() so both
the attach path and the link update path are covered by a single check
at the actual install site.

Fixes: 026a4c2 ("bpf, xdp: Implement LINK_UPDATE for BPF XDP link")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant