mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-16 07:52:22 -04:00
Payload guards a truncated packet by comparing both length and dataofs against len(b), but the slice it returns is b[dataofs:length], so what actually has to hold is dataofs <= length. Those are independent: length comes from the IPv4 total length header field, while dataofs is derived from the sub-protocol header, and decode4 never checks that the declared total length covers the transport header. A 28-byte IPv4/UDP packet declaring a total length of 20 decodes to length=20, dataofs=28, len(b)=28, and Payload then evaluates b[28:20]. ICMPv4 and TCP reach the same state with 24- and 40-byte packets. I found this by fuzzing Decode and then calling the accessors on the result. I did not find a caller that can be driven into it from the network: wireguard-go truncates decrypted packets to the declared IP length, so on the inbound path dataofs > length implies dataofs > len(b) and the existing guard already catches it. Add a FuzzParsedPayload target that decodes and then calls Payload, seeded with valid IPv4/IPv6 packets and with invalid ones, including the three short total length packets above, and build it in fuzz/oss-fuzz.sh. Fixes #21231 Change-Id: Ie5d2100464b79750626b1bfefbe4020c4a42ca91 Signed-off-by: leoca <leo.camus23@gmail.com>