From: Greg Kroah-Hartman Date: Thu, 19 Mar 2026 12:01:03 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v6.18.19~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3954ebcc7192d33e18657fbeae92337f8a5fcacf;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: bpf-forget-ranges-when-refining-tnum-after-jset.patch l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch --- diff --git a/queue-6.1/bpf-forget-ranges-when-refining-tnum-after-jset.patch b/queue-6.1/bpf-forget-ranges-when-refining-tnum-after-jset.patch new file mode 100644 index 0000000000..2ae6157187 --- /dev/null +++ b/queue-6.1/bpf-forget-ranges-when-refining-tnum-after-jset.patch @@ -0,0 +1,68 @@ +From 6279846b9b2532e1b04559ef8bd0dec049f29383 Mon Sep 17 00:00:00 2001 +From: Paul Chaignon +Date: Thu, 10 Jul 2025 20:20:53 +0200 +Subject: bpf: Forget ranges when refining tnum after JSET + +From: Paul Chaignon + +commit 6279846b9b2532e1b04559ef8bd0dec049f29383 upstream. + +Syzbot reported a kernel warning due to a range invariant violation on +the following BPF program. + + 0: call bpf_get_netns_cookie + 1: if r0 == 0 goto + 2: if r0 & Oxffffffff goto + +The issue is on the path where we fall through both jumps. + +That path is unreachable at runtime: after insn 1, we know r0 != 0, but +with the sign extension on the jset, we would only fallthrough insn 2 +if r0 == 0. Unfortunately, is_branch_taken() isn't currently able to +figure this out, so the verifier walks all branches. The verifier then +refines the register bounds using the second condition and we end +up with inconsistent bounds on this unreachable path: + + 1: if r0 == 0 goto + r0: u64=[0x1, 0xffffffffffffffff] var_off=(0, 0xffffffffffffffff) + 2: if r0 & 0xffffffff goto + r0 before reg_bounds_sync: u64=[0x1, 0xffffffffffffffff] var_off=(0, 0) + r0 after reg_bounds_sync: u64=[0x1, 0] var_off=(0, 0) + +Improving the range refinement for JSET to cover all cases is tricky. We +also don't expect many users to rely on JSET given LLVM doesn't generate +those instructions. So instead of improving the range refinement for +JSETs, Eduard suggested we forget the ranges whenever we're narrowing +tnums after a JSET. This patch implements that approach. + +Reported-by: syzbot+c711ce17dd78e5d4fdcf@syzkaller.appspotmail.com +Suggested-by: Eduard Zingerman +Acked-by: Yonghong Song +Acked-by: Eduard Zingerman +Signed-off-by: Paul Chaignon +Link: https://lore.kernel.org/r/9d4fd6432a095d281f815770608fdcd16028ce0b.1752171365.git.paul.chaignon@gmail.com +Signed-off-by: Alexei Starovoitov +[ shung-hsi.yu: no detection or kernel warning for invariant violation before + 6.8, but the same umin=1,umax=0 state can occur when jset is preceed by r0 < 1. + Changes were made to adapt to older range refinement logic before commit + 67420501e868 ("bpf: generalize reg_set_min_max() to handle non-const register + comparisons"). ] +Signed-off-by: Shung-Hsi Yu +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -10012,6 +10012,10 @@ static void reg_set_min_max(struct bpf_r + } + break; + case BPF_JSET: ++ /* Forget the ranges before narrowing tnums, to avoid invariant ++ * violations if we're on a dead branch. ++ */ ++ __mark_reg_unbounded(false_reg); + if (is_jmp32) { + false_32off = tnum_and(false_32off, tnum_const(~val32)); + if (is_power_of_2(val32)) diff --git a/queue-6.1/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch b/queue-6.1/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch new file mode 100644 index 0000000000..fa18d675d5 --- /dev/null +++ b/queue-6.1/l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch @@ -0,0 +1,108 @@ +From 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 26 Aug 2025 13:44:35 +0000 +Subject: l2tp: do not use sock_hold() in pppol2tp_session_get_sock() + +From: Eric Dumazet + +commit 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 upstream. + +pppol2tp_session_get_sock() is using RCU, it must be ready +for sk_refcnt being zero. + +Commit ee40fb2e1eb5 ("l2tp: protect sock pointer of +struct pppol2tp_session with RCU") was correct because it +had a call_rcu(..., pppol2tp_put_sk) which was later removed in blamed commit. + +pppol2tp_recv() can use pppol2tp_session_get_sock() as well. + +Fixes: c5cbaef992d6 ("l2tp: refactor ppp socket/session relationship") +Signed-off-by: Eric Dumazet +Cc: James Chapman +Reviewed-by: Guillaume Nault +Link: https://patch.msgid.link/20250826134435.1683435-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Qingfang Deng +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 25 ++++++++----------------- + 1 file changed, 8 insertions(+), 17 deletions(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -130,22 +130,12 @@ static const struct ppp_channel_ops pppo + + static const struct proto_ops pppol2tp_ops; + +-/* Retrieves the pppol2tp socket associated to a session. +- * A reference is held on the returned socket, so this function must be paired +- * with sock_put(). +- */ ++/* Retrieves the pppol2tp socket associated to a session. */ + static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session) + { + struct pppol2tp_session *ps = l2tp_session_priv(session); +- struct sock *sk; + +- rcu_read_lock(); +- sk = rcu_dereference(ps->sk); +- if (sk) +- sock_hold(sk); +- rcu_read_unlock(); +- +- return sk; ++ return rcu_dereference(ps->sk); + } + + /* Helpers to obtain tunnel/session contexts from sockets. +@@ -211,14 +201,13 @@ end: + + static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len) + { +- struct pppol2tp_session *ps = l2tp_session_priv(session); +- struct sock *sk = NULL; ++ struct sock *sk; + + /* If the socket is bound, send it in to PPP's input queue. Otherwise + * queue it on the session socket. + */ + rcu_read_lock(); +- sk = rcu_dereference(ps->sk); ++ sk = pppol2tp_session_get_sock(session); + if (!sk) + goto no_sock; + +@@ -528,13 +517,14 @@ static void pppol2tp_show(struct seq_fil + struct l2tp_session *session = arg; + struct sock *sk; + ++ rcu_read_lock(); + sk = pppol2tp_session_get_sock(session); + if (sk) { + struct pppox_sock *po = pppox_sk(sk); + + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); +- sock_put(sk); + } ++ rcu_read_unlock(); + } + + static void pppol2tp_session_init(struct l2tp_session *session) +@@ -1540,6 +1530,7 @@ static void pppol2tp_seq_session_show(st + port = ntohs(inet->inet_sport); + } + ++ rcu_read_lock(); + sk = pppol2tp_session_get_sock(session); + if (sk) { + state = sk->sk_state; +@@ -1575,8 +1566,8 @@ static void pppol2tp_seq_session_show(st + struct pppox_sock *po = pppox_sk(sk); + + seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan)); +- sock_put(sk); + } ++ rcu_read_unlock(); + } + + static int pppol2tp_seq_show(struct seq_file *m, void *v) diff --git a/queue-6.1/series b/queue-6.1/series index c073a6a549..bbbcc112f1 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -275,3 +275,5 @@ i3c-mipi-i3c-hci-restart-dma-ring-correctly-after-dequeue-abort.patch i3c-mipi-i3c-hci-add-missing-tid-field-to-no-op-command-descriptor.patch drm-bridge-ti-sn65dsi86-add-support-for-displayport-mode-with-hpd.patch ipv6-use-rcu-in-ip6_xmit.patch +bpf-forget-ranges-when-refining-tnum-after-jset.patch +l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_sock.patch