diff options
| author | Weiming Shi <bestswngs@gmail.com> | 2026-03-04 12:42:18 +0800 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-06 17:45:37 -0800 |
| commit | 0cc0c2e661af418bbf7074179ea5cfffc0a5c466 (patch) | |
| tree | 903971c9d198a06ae5cf5cd56bde12be25eda23b /net | |
| parent | 5c3398a54266541610c8d0a7082e654e9ff3e259 (diff) | |
net/sched: teql: fix NULL pointer dereference in iptunnel_xmit on TEQL slave xmit
teql_master_xmit() calls netdev_start_xmit(skb, slave) to transmit
through slave devices, but does not update skb->dev to the slave device
beforehand.
When a gretap tunnel is a TEQL slave, the transmit path reaches
iptunnel_xmit() which saves dev = skb->dev (still pointing to teql0
master) and later calls iptunnel_xmit_stats(dev, pkt_len). This
function does:
get_cpu_ptr(dev->tstats)
Since teql_master_setup() does not set dev->pcpu_stat_type to
NETDEV_PCPU_STAT_TSTATS, the core network stack never allocates tstats
for teql0, so dev->tstats is NULL. get_cpu_ptr(NULL) computes
NULL + __per_cpu_offset[cpu], resulting in a page fault.
BUG: unable to handle page fault for address: ffff8880e6659018
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
PGD 68bc067 P4D 68bc067 PUD 0
Oops: Oops: 0002 [#1] SMP KASAN PTI
RIP: 0010:iptunnel_xmit (./include/net/ip_tunnels.h:664 net/ipv4/ip_tunnel_core.c:89)
Call Trace:
<TASK>
ip_tunnel_xmit (net/ipv4/ip_tunnel.c:847)
__gre_xmit (net/ipv4/ip_gre.c:478)
gre_tap_xmit (net/ipv4/ip_gre.c:779)
teql_master_xmit (net/sched/sch_teql.c:319)
dev_hard_start_xmit (net/core/dev.c:3887)
sch_direct_xmit (net/sched/sch_generic.c:347)
__dev_queue_xmit (net/core/dev.c:4802)
neigh_direct_output (net/core/neighbour.c:1660)
ip_finish_output2 (net/ipv4/ip_output.c:237)
__ip_finish_output.part.0 (net/ipv4/ip_output.c:315)
ip_mc_output (net/ipv4/ip_output.c:369)
ip_send_skb (net/ipv4/ip_output.c:1508)
udp_send_skb (net/ipv4/udp.c:1195)
udp_sendmsg (net/ipv4/udp.c:1485)
inet_sendmsg (net/ipv4/af_inet.c:859)
__sys_sendto (net/socket.c:2206)
Fix this by setting skb->dev = slave before calling
netdev_start_xmit(), so that tunnel xmit functions see the correct
slave device with properly allocated tstats.
Fixes: 039f50629b7f ("ip_tunnel: Move stats update to iptunnel_xmit()")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20260304044216.3517851-3-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/sched/sch_teql.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 6e4bdaa876ed..783300d8b019 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -315,6 +315,7 @@ restart: if (__netif_tx_trylock(slave_txq)) { unsigned int length = qdisc_pkt_len(skb); + skb->dev = slave; if (!netif_xmit_frozen_or_stopped(slave_txq) && netdev_start_xmit(skb, slave, slave_txq, false) == NETDEV_TX_OK) { |
