* [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom
@ 2026-02-27 22:07 David Bauer
2026-02-27 22:07 ` [PATCH net-next 2/2] l2tp: unify headroom calculation David Bauer
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: David Bauer @ 2026-02-27 22:07 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: netdev, linux-kernel
Account for the IP version of the tunnel when accounting skb headroom on
xmit. This avoids having to potentially copy the skb a second time down
the stack due to allocating not enough space for IPv6 headers in case
the tunnel uses IPv6.
Signed-off-by: David Bauer <mail@david-bauer.net>
---
net/l2tp/l2tp_core.c | 3 ++-
net/l2tp/l2tp_core.h | 1 +
net/l2tp/l2tp_eth.c | 9 ++-------
3 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index c89ae52764b89..bb19c11b0af8e 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1236,7 +1236,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
* make room. Adjust truesize.
*/
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(*uh) : 0;
- headroom = NET_SKB_PAD + sizeof(struct iphdr) + uhlen + session->hdr_len;
+ headroom = NET_SKB_PAD + tunnel->l3_overhead + uhlen + session->hdr_len;
if (skb_cow_head(skb, headroom)) {
kfree_skb(skb);
return NET_XMIT_DROP;
@@ -1682,6 +1682,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net,
}
sk->sk_allocation = GFP_ATOMIC;
+ tunnel->l3_overhead = kernel_sock_ip_overhead(sk);
release_sock(sk);
sock_hold(sk);
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index ffd8ced3a51ff..aab574376d95f 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -167,6 +167,7 @@ struct l2tp_tunnel {
u32 tunnel_id;
u32 peer_tunnel_id;
int version; /* 2=>L2TPv2, 3=>L2TPv3 */
+ int l3_overhead; /* IP header overhead */
char name[L2TP_TUNNEL_NAME_MAX]; /* for logging */
enum l2tp_encap_type encap;
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index a4956ef9574cc..9e5f9deac08cf 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -188,7 +188,6 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
struct net_device *dev)
{
unsigned int overhead = 0;
- u32 l3_overhead = 0;
u32 mtu;
/* if the encap is UDP, account for UDP header size */
@@ -197,11 +196,7 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
dev->needed_headroom += sizeof(struct udphdr);
}
- lock_sock(tunnel->sock);
- l3_overhead = kernel_sock_ip_overhead(tunnel->sock);
- release_sock(tunnel->sock);
-
- if (l3_overhead == 0) {
+ if (tunnel->l3_overhead == 0) {
/* L3 Overhead couldn't be identified, this could be
* because tunnel->sock was NULL or the socket's
* address family was not IPv4 or IPv6,
@@ -212,7 +207,7 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
/* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr
* UDP overhead, if any, was already factored in above.
*/
- overhead += session->hdr_len + ETH_HLEN + l3_overhead;
+ overhead += session->hdr_len + ETH_HLEN + tunnel->l3_overhead;
mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead;
if (mtu < dev->min_mtu || mtu > dev->max_mtu)
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net-next 2/2] l2tp: unify headroom calculation
2026-02-27 22:07 [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom David Bauer
@ 2026-02-27 22:07 ` David Bauer
2026-02-28 15:35 ` [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom Jakub Kicinski
2026-02-28 22:12 ` [syzbot ci] " syzbot ci
2 siblings, 0 replies; 4+ messages in thread
From: David Bauer @ 2026-02-27 22:07 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: netdev, linux-kernel
Unify the calculation to determine the required headroom for each skb.
This was previously done inconsistently, resulting requesting more space
in the skb headroom when crafting the L2TP header than indicated with
needed_headroom.
Signed-off-by: David Bauer <mail@david-bauer.net>
---
net/l2tp/l2tp_core.c | 8 +++-----
net/l2tp/l2tp_core.h | 17 +++++++++++++++++
net/l2tp/l2tp_eth.c | 14 +++-----------
3 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index bb19c11b0af8e..a726bdc0d6204 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1226,18 +1226,16 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
struct l2tp_tunnel *tunnel = session->tunnel;
unsigned int data_len = skb->len;
struct sock *sk = tunnel->sock;
- int headroom, uhlen, udp_len;
int ret = NET_XMIT_SUCCESS;
struct inet_sock *inet;
struct udphdr *uh;
+ int udp_len;
/* Check that there's enough headroom in the skb to insert IP,
* UDP and L2TP headers. If not enough, expand it to
* make room. Adjust truesize.
*/
- uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(*uh) : 0;
- headroom = NET_SKB_PAD + tunnel->l3_overhead + uhlen + session->hdr_len;
- if (skb_cow_head(skb, headroom)) {
+ if (skb_cow_head(skb, l2tp_session_skb_headroom(session))) {
kfree_skb(skb);
return NET_XMIT_DROP;
}
@@ -1289,7 +1287,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns
uh = udp_hdr(skb);
uh->source = inet->inet_sport;
uh->dest = inet->inet_dport;
- udp_len = uhlen + session->hdr_len + data_len;
+ udp_len = l2tp_session_udp_hdrlen(session) + session->hdr_len + data_len;
uh->len = htons(udp_len);
/* Calculate UDP checksum if configured to do so */
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index aab574376d95f..635a6e01f417a 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -335,6 +335,23 @@ static inline int l2tp_v3_ensure_opt_in_linear(struct l2tp_session *session, str
return 0;
}
+static inline int l2tp_session_udp_hdrlen(struct l2tp_session *session)
+{
+ return session->tunnel->encap == L2TP_ENCAPTYPE_UDP ?
+ sizeof(struct udphdr) : 0;
+}
+
+static inline int l2tp_session_overhead(struct l2tp_session *session)
+{
+ return l2tp_session_udp_hdrlen(session) + session->hdr_len +
+ session->tunnel->l3_overhead;
+}
+
+static inline int l2tp_session_skb_headroom(struct l2tp_session *session)
+{
+ return NET_SKB_PAD + l2tp_session_overhead(session);
+}
+
#define MODULE_ALIAS_L2TP_PWTYPE(type) \
MODULE_ALIAS("net-l2tp-type-" __stringify(type))
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 9e5f9deac08cf..29380fae02475 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -190,12 +190,6 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
unsigned int overhead = 0;
u32 mtu;
- /* if the encap is UDP, account for UDP header size */
- if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
- overhead += sizeof(struct udphdr);
- dev->needed_headroom += sizeof(struct udphdr);
- }
-
if (tunnel->l3_overhead == 0) {
/* L3 Overhead couldn't be identified, this could be
* because tunnel->sock was NULL or the socket's
@@ -204,10 +198,8 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
*/
return;
}
- /* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr
- * UDP overhead, if any, was already factored in above.
- */
- overhead += session->hdr_len + ETH_HLEN + tunnel->l3_overhead;
+ /* Calculate required overhead */
+ overhead = ETH_HLEN + l2tp_session_overhead(session);
mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead;
if (mtu < dev->min_mtu || mtu > dev->max_mtu)
@@ -215,7 +207,7 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
else
dev->mtu = mtu;
- dev->needed_headroom += session->hdr_len;
+ dev->needed_headroom = l2tp_session_skb_headroom(session);
}
static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
--
2.51.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom
2026-02-27 22:07 [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom David Bauer
2026-02-27 22:07 ` [PATCH net-next 2/2] l2tp: unify headroom calculation David Bauer
@ 2026-02-28 15:35 ` Jakub Kicinski
2026-02-28 22:12 ` [syzbot ci] " syzbot ci
2 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2026-02-28 15:35 UTC (permalink / raw)
To: David Bauer
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman, netdev,
linux-kernel
On Fri, 27 Feb 2026 23:07:37 +0100 David Bauer wrote:
> Account for the IP version of the tunnel when accounting skb headroom on
> xmit. This avoids having to potentially copy the skb a second time down
> the stack due to allocating not enough space for IPv6 headers in case
> the tunnel uses IPv6.
This appears to crash immediately in the net/l2tp.sh selftest:
# selftests: net: l2tp.sh
# 0.27 [+0.27] ./l2tp.sh: line 138: 22310 Killed ip -netns $host_1 l2tp add session name l2tp4 tunnel_id 1041 session_id 1041 peer_session_id 1042
not ok 1 selftests: net: l2tp.sh # exit=137
[ 1585.224860] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[ 1585.224891] RIP: 0010:l2tp_eth_create+0xf2/0x300 [l2tp_eth]
[ 1585.225362] <TASK>
[ 1585.225377] l2tp_nl_cmd_session_create+0x204/0x470 [l2tp_netlink]
--
pw-bot: cr
^ permalink raw reply [flat|nested] 4+ messages in thread
* [syzbot ci] Re: l2tp: account for IP version in SKB headroom
2026-02-27 22:07 [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom David Bauer
2026-02-27 22:07 ` [PATCH net-next 2/2] l2tp: unify headroom calculation David Bauer
2026-02-28 15:35 ` [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom Jakub Kicinski
@ 2026-02-28 22:12 ` syzbot ci
2 siblings, 0 replies; 4+ messages in thread
From: syzbot ci @ 2026-02-28 22:12 UTC (permalink / raw)
To: davem, edumazet, horms, kuba, linux-kernel, mail, netdev, pabeni
Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v1] l2tp: account for IP version in SKB headroom
https://lore.kernel.org/all/20260227220740.11928-1-mail@david-bauer.net
* [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom
* [PATCH net-next 2/2] l2tp: unify headroom calculation
and found the following issue:
general protection fault in l2tp_eth_create
Full report is available here:
https://ci.syzbot.org/series/10f6234e-88a0-41c8-b9d2-a3e54f289fbd
***
general protection fault in l2tp_eth_create
tree: net-next
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net-next.git
base: 58e443b773ef054ae069cf777ba19adb99d73829
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/66fb3a44-8edb-4c92-9149-328653e46ccd/config
C repro: https://ci.syzbot.org/findings/9b3d30fe-b87f-4b00-99a6-464f0a271312/c_repro
syz repro: https://ci.syzbot.org/findings/9b3d30fe-b87f-4b00-99a6-464f0a271312/syz_repro
netlink: 8 bytes leftover after parsing attributes in process `syz.0.17'.
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
CPU: 1 UID: 0 PID: 5971 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:l2tp_session_udp_hdrlen net/l2tp/l2tp_core.h:340 [inline]
RIP: 0010:l2tp_session_overhead net/l2tp/l2tp_core.h:346 [inline]
RIP: 0010:l2tp_eth_adjust_mtu net/l2tp/l2tp_eth.c:202 [inline]
RIP: 0010:l2tp_eth_create+0x2cd/0xca0 net/l2tp/l2tp_eth.c:250
Code: 48 89 44 24 58 42 80 3c 28 00 74 08 48 89 df e8 b9 68 54 f7 48 89 5c 24 60 4c 8b 33 4d 8d a6 94 00 00 00 4c 89 e0 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 35 08 00 00 45 8b 24 24 31 ff 44 89 e6
RSP: 0018:ffffc900040c7160 EFLAGS: 00010207
RAX: 0000000000000012 RBX: ffff888114d00020 RCX: 0000000000000000
RDX: ffff888104f90000 RSI: 0000000000000028 RDI: 0000000000000000
RBP: ffffc900040c7270 R08: 0000000000400dc0 R09: 00000000ffffffff
R10: dffffc0000000000 R11: fffffbfff2022f77 R12: 0000000000000094
R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888114d00000
FS: 0000555574b08500(0000) GS:ffff8882a9467000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055a269259270 CR3: 0000000105770000 CR4: 00000000000006f0
Call Trace:
<TASK>
l2tp_nl_cmd_session_create+0x766/0xc60 net/l2tp/l2tp_netlink.c:639
genl_family_rcv_msg_doit+0x22a/0x330 net/netlink/genetlink.c:1114
genl_family_rcv_msg net/netlink/genetlink.c:1194 [inline]
genl_rcv_msg+0x61c/0x7a0 net/netlink/genetlink.c:1209
netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg net/socket.c:742 [inline]
____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
__sys_sendmsg net/socket.c:2678 [inline]
__do_sys_sendmsg net/socket.c:2683 [inline]
__se_sys_sendmsg net/socket.c:2681 [inline]
__x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f371079c799
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff7e0100f8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007f3710a15fa0 RCX: 00007f371079c799
RDX: 0000000020000034 RSI: 0000200000000140 RDI: 0000000000000005
RBP: 00007f3710832bd9 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f3710a15fac R14: 00007f3710a15fa0 R15: 00007f3710a15fa0
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:l2tp_session_udp_hdrlen net/l2tp/l2tp_core.h:340 [inline]
RIP: 0010:l2tp_session_overhead net/l2tp/l2tp_core.h:346 [inline]
RIP: 0010:l2tp_eth_adjust_mtu net/l2tp/l2tp_eth.c:202 [inline]
RIP: 0010:l2tp_eth_create+0x2cd/0xca0 net/l2tp/l2tp_eth.c:250
Code: 48 89 44 24 58 42 80 3c 28 00 74 08 48 89 df e8 b9 68 54 f7 48 89 5c 24 60 4c 8b 33 4d 8d a6 94 00 00 00 4c 89 e0 48 c1 e8 03 <42> 0f b6 04 28 84 c0 0f 85 35 08 00 00 45 8b 24 24 31 ff 44 89 e6
RSP: 0018:ffffc900040c7160 EFLAGS: 00010207
RAX: 0000000000000012 RBX: ffff888114d00020 RCX: 0000000000000000
RDX: ffff888104f90000 RSI: 0000000000000028 RDI: 0000000000000000
RBP: ffffc900040c7270 R08: 0000000000400dc0 R09: 00000000ffffffff
R10: dffffc0000000000 R11: fffffbfff2022f77 R12: 0000000000000094
R13: dffffc0000000000 R14: 0000000000000000 R15: ffff888114d00000
FS: 0000555574b08500(0000) GS:ffff8882a9467000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055a269259270 CR3: 0000000105770000 CR4: 00000000000006f0
----------------
Code disassembly (best guess):
0: 48 89 44 24 58 mov %rax,0x58(%rsp)
5: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1)
a: 74 08 je 0x14
c: 48 89 df mov %rbx,%rdi
f: e8 b9 68 54 f7 call 0xf75468cd
14: 48 89 5c 24 60 mov %rbx,0x60(%rsp)
19: 4c 8b 33 mov (%rbx),%r14
1c: 4d 8d a6 94 00 00 00 lea 0x94(%r14),%r12
23: 4c 89 e0 mov %r12,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 42 0f b6 04 28 movzbl (%rax,%r13,1),%eax <-- trapping instruction
2f: 84 c0 test %al,%al
31: 0f 85 35 08 00 00 jne 0x86c
37: 45 8b 24 24 mov (%r12),%r12d
3b: 31 ff xor %edi,%edi
3d: 44 89 e6 mov %r12d,%esi
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-02-28 22:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-27 22:07 [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom David Bauer
2026-02-27 22:07 ` [PATCH net-next 2/2] l2tp: unify headroom calculation David Bauer
2026-02-28 15:35 ` [PATCH net-next 1/2] l2tp: account for IP version in SKB headroom Jakub Kicinski
2026-02-28 22:12 ` [syzbot ci] " syzbot ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox