freenode
Kernel & Low-Level

Two-decade IPv6 MTU bug can panic Linux with one sendmsg

Dead code in the IPv6 append path left a narrow MTU window that underflows and lets unprivileged raw-socket traffic trip skb_over_panic.

A kernel BUG that has sat in Linux IPv6 output since the 2.6.12 era can be triggered by an unprivileged process with a single sendmsg on a raw IPv6 socket, according to a report and fix posted to the netdev list.

Bo Cao traced the failure to a broken MTU check in the path that builds IPv6 fragments. One half of that guard has been dead code for the life of the tree: it can never fire given a normal IPv6 header length. A 2022 change closed the equal-to-header boundary after a syzbot report, but left the useless second clause in place.

When the path MTU exceeds the fragment header length by only one to seven bytes, length math underflows. Later clamps wrap instead of limiting the payload, so the stack can call skb_put with a size far larger than the buffer it allocated. On an egress device without scatter-gather and with MSG_MORE, that becomes an immediate skb_over_panic and a kernel oops. Cao reproduced it with a self-contained C program that creates its own egress device, sets a tight IPV6_MTU, and attaches a large hop-by-hop options cmsg.

The proposed fix replaces the dead expression with a direct check that there is enough room for fragment payload, rejecting the one-to-eight-byte leftover range. Greg Kroah-Hartman asked for a proper patch so the reporter could take credit; Willem de Bruijn reviewed the change and corrected the Fixes tag to the commit that actually introduced the weak guard.

The flaw matters because raw IPv6 sockets and per-socket MTU are ordinary unprivileged interfaces on many systems, and a local oops is a reliable denial of service. The code is unchanged through current mainline release candidates, and the patch is aimed at stable as well.