diff options
Diffstat (limited to 'debian/patches-rt/tun-Assign-missing-bpf_net_context.patch')
-rw-r--r-- | debian/patches-rt/tun-Assign-missing-bpf_net_context.patch | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/debian/patches-rt/tun-Assign-missing-bpf_net_context.patch b/debian/patches-rt/tun-Assign-missing-bpf_net_context.patch new file mode 100644 index 0000000000..1d16417b19 --- /dev/null +++ b/debian/patches-rt/tun-Assign-missing-bpf_net_context.patch @@ -0,0 +1,114 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 4 Jul 2024 16:48:15 +0200 +Subject: [PATCH] tun: Assign missing bpf_net_context. +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.10/older/patches-6.10.2-rt14.tar.xz + +During the introduction of struct bpf_net_context handling for +XDP-redirect, the tun driver has been missed. +Jakub also pointed out that there is another call chain to +do_xdp_generic() originating from netif_receive_skb() and drivers may +use it outside from the NAPI context. + +Set the bpf_net_context before invoking BPF XDP program within the TUN +driver. Set the bpf_net_context also in do_xdp_generic() if a xdp +program is available. + +Reported-by: syzbot+0b5c75599f1d872bea6f@syzkaller.appspotmail.com +Reported-by: syzbot+5ae46b237278e2369cac@syzkaller.appspotmail.com +Reported-by: syzbot+c1e04a422bbc0f0f2921@syzkaller.appspotmail.com +Fixes: 401cb7dae8130 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.") +Link: https://lore.kernel.org/r/20240704144815.j8xQda5r@linutronix.de +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/net/tun.c | 7 +++++++ + net/core/dev.c | 5 +++++ + 2 files changed, 12 insertions(+) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1661,6 +1661,7 @@ static struct sk_buff *tun_build_skb(str + int len, int *skb_xdp) + { + struct page_frag *alloc_frag = ¤t->task_frag; ++ struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx; + struct bpf_prog *xdp_prog; + int buflen = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + char *buf; +@@ -1700,6 +1701,7 @@ static struct sk_buff *tun_build_skb(str + + local_bh_disable(); + rcu_read_lock(); ++ bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx); + xdp_prog = rcu_dereference(tun->xdp_prog); + if (xdp_prog) { + struct xdp_buff xdp; +@@ -1728,12 +1730,14 @@ static struct sk_buff *tun_build_skb(str + pad = xdp.data - xdp.data_hard_start; + len = xdp.data_end - xdp.data; + } ++ bpf_net_ctx_clear(bpf_net_ctx); + rcu_read_unlock(); + local_bh_enable(); + + return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, pad); + + out: ++ bpf_net_ctx_clear(bpf_net_ctx); + rcu_read_unlock(); + local_bh_enable(); + return NULL; +@@ -2566,6 +2570,7 @@ static int tun_sendmsg(struct socket *so + + if (m->msg_controllen == sizeof(struct tun_msg_ctl) && + ctl && ctl->type == TUN_MSG_PTR) { ++ struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx; + struct tun_page tpage; + int n = ctl->num; + int flush = 0, queued = 0; +@@ -2574,6 +2579,7 @@ static int tun_sendmsg(struct socket *so + + local_bh_disable(); + rcu_read_lock(); ++ bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx); + + for (i = 0; i < n; i++) { + xdp = &((struct xdp_buff *)ctl->ptr)[i]; +@@ -2588,6 +2594,7 @@ static int tun_sendmsg(struct socket *so + if (tfile->napi_enabled && queued > 0) + napi_schedule(&tfile->napi); + ++ bpf_net_ctx_clear(bpf_net_ctx); + rcu_read_unlock(); + local_bh_enable(); + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -5126,11 +5126,14 @@ static DEFINE_STATIC_KEY_FALSE(generic_x + + int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff **pskb) + { ++ struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx; ++ + if (xdp_prog) { + struct xdp_buff xdp; + u32 act; + int err; + ++ bpf_net_ctx = bpf_net_ctx_set(&__bpf_net_ctx); + act = netif_receive_generic_xdp(pskb, &xdp, xdp_prog); + if (act != XDP_PASS) { + switch (act) { +@@ -5144,11 +5147,13 @@ int do_xdp_generic(struct bpf_prog *xdp_ + generic_xdp_tx(*pskb, xdp_prog); + break; + } ++ bpf_net_ctx_clear(bpf_net_ctx); + return XDP_DROP; + } + } + return XDP_PASS; + out_redir: ++ bpf_net_ctx_clear(bpf_net_ctx); + kfree_skb_reason(*pskb, SKB_DROP_REASON_XDP); + return XDP_DROP; + } |