A 6LoWPAN fragment announces the total size of the datagram it belongs to (d_size) and its own offset within that datagram. The reassembly code never checks that the offset actually fits inside d_size, so a fragment claiming to start far past the end of the datagram is accepted the same as a legitimate one, allowing an attacker to forge data of another sender. lowpan_frag_queue() considers a datagram complete by counting bytes received (fq->q.meat) against the declared size (fq->q.len), not by verifying the bytes form a contiguous range. A fragment with an out-of-range offset still has its length counted toward that total, so a legitimate fragment exchange plus an attacker fragment can sum to d_size, marking the datagram complete while a gap in the data was never filled, and appending the out-of-range fragment's bytes to the end of the reassembled buffer as if they were part of the message. IPv6's reassembly (net/ipv6/reassembly.c, ip6_frag_queue()) computes end = offset + payload length for every fragment and checks end against IPV6_MAXPLEN, which bounds offset by construction. 6LoWPAN's d_offset and d_size are independent wire fields with no such coupling, and no separate bounds check was added for it. The same class of bug was assigned CVE-2019-8359 (CVSS 9.8) in Contiki-NG's 6LoWPAN stack before a 2019 fix; RIOT-OS's implementation (gnrc_sixlowpan_frag_rb_add) rejects a fragment once offset + size exceeds the reassembly buffer's datagram_size. Linux's 6LoWPAN reassembly is the only one of these implementations without an equivalent check. Fix by rejecting any fragment whose offset, or offset plus length, falls outside [0, d_size). Reproduced two ways: with a local kernel module calling lowpan_frag_rcv() directly, and over mac802154_hwsim with three independent processes standing in for sender, receiver and attacker. An attacker in radio range who observes one fragment of an in-progress transmission reads d_tag, d_size and the addressing in the clear, then sends a single out-of-range fragment of its own. The receiver's reassembly completes with the attacker's bytes appended to the legitimate data. Both reproducers were re-run against this fix to confirm the out-of-range fragment is now rejected and the datagram no longer completes with it included. AI Disclosure: An AI assistant (Claude) was used to assist with the analysis and testing. I have verified the vulnerability, the fix, and the test results myself and take responsibility for this contribution, per Documentation/process/coding-assistants.rst. Fixes: 7240cdec60b1 ("6lowpan: handling 6lowpan fragmentation via inet_frag api") Signed-off-by: Ryan Prinz --- Resending with correct tree designator in the subject net/ieee802154/6lowpan/reassembly.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c index ddb6a5817d09..905ba5f86844 100644 --- a/net/ieee802154/6lowpan/reassembly.c +++ b/net/ieee802154/6lowpan/reassembly.c @@ -103,6 +103,9 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq, offset = lowpan_802154_cb(skb)->d_offset << 3; end = lowpan_802154_cb(skb)->d_size; + if (offset > end || skb->len > end - offset) + goto err; + /* Is this the final fragment? */ if (offset + skb->len == end) { /* If we already have some bits beyond end -- 2.51.2