Re: [PATCH net] seg6: keep room for the mac header when growing the headroom

From: Justin Iurman

Date: Thu Sep 17 2026 - 17:46:36 EST


On 9/17/26 18:28, Andrea Mayer wrote:
On Thu, 17 Sep 2026 12:12:11 +0200
Justin Iurman <justin.iurman@xxxxxxxxx> wrote:

On 9/16/26 23:38, Yuya Kusakabe wrote:
[snip]

Overall, LGTM, thanks. However, I think we'd need a v2 with the followings:

- use max_t(unsigned int, skb->mac_len, dst_dev_overhead(cache_dst,
skb)) instead of max()
- apply the same changes to ioam6_iptunnel and rpl_iptunnel (all in one
patch is fine)

Reviewed-by: Justin Iurman <justin.iurman@xxxxxxxxx>

Hi Justin,

Agreed, rpl and ioam6 inline do trigger. Single VLAN device per side,
reorder_hdr off on the receiving one, plain ping:

BUG: KASAN: slab-out-of-bounds in rpl_do_srh_inline.isra.0+0x3d3/0x770
Write of size 18 at addr ffff88810deeba7e by task ping/447

CPU: 0 UID: 0 PID: 447 Comm: ping Not tainted 7.3.0-rc1 #364
Call Trace:
<IRQ>
__asan_memmove+0x38/0x60
rpl_do_srh_inline.isra.0+0x3d3/0x770
rpl_input+0xd3/0x5e0
lwtunnel_input+0x18d/0x420
ipv6_rcv+0x452/0x460

BUG: KASAN: slab-use-after-free in ioam6_do_inline+0x2d8/0x5e0
Write of size 18 at addr ffff88811480fa7e by task ping/432

CPU: 0 UID: 0 PID: 432 Comm: ping Not tainted 7.3.0-rc1 #364
Call Trace:
<IRQ>
__asan_memmove+0x38/0x60
ioam6_do_inline+0x2d8/0x5e0
ioam6_output+0x335/0x970
lwtunnel_output+0x1b0/0x440
ip6_forward+0x16a7/0x16f0
ipv6_rcv+0x452/0x460

ioam6_do_encap triggers too, with three VLAN tags via tc push:

BUG: KASAN: use-after-free in ioam6_do_encap+0x202/0x5c0
Write of size 26 at addr ffff88810de227fe by task ping/453

CPU: 0 UID: 0 PID: 453 Comm: ping Not tainted 7.3.0-rc1 #364
Call Trace:
<IRQ>
__asan_memmove+0x38/0x60
ioam6_do_encap+0x202/0x5c0
ioam6_output+0x3cc/0x970
lwtunnel_output+0x1b0/0x440
ip6_forward+0x16a7/0x16f0
ipv6_rcv+0x452/0x460

I would fix dst_dev_overhead() itself rather than patching every
caller individually, that covers all callers at once and protects
any future user of the helper. dst_dev_overhead() already returns
skb->mac_len when dst is NULL, the fix would make the other branch
consistent:

--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -455,7 +455,8 @@ static inline unsigned int dst_dev_overhead(struct dst_entry *dst,
struct sk_buff *skb)
{
if (likely(dst))
- return LL_RESERVED_SPACE(dst->dev);
+ return max_t(unsigned int, skb->mac_len,
+ LL_RESERVED_SPACE(dst->dev));

return skb->mac_len;
}

+1. That's even better, thanks!