On Thu, 25 Jun 2026 at 05:53, Akihiko Odaki <[email protected]> wrote: > > On 2026/06/25 6:45, Sanjeeva Yerrapureddy wrote: > > When a guest transmits a short Ethernet frame, iov_size() returns the > > wire length including any Ethernet padding bytes added to reach the > > minimum 60-byte frame size. net_tx_pkt_rebuild_payload() used that > > inflated size directly as payload_len. net_tx_pkt_update_ip_hdr_ > > checksum() then rewrites the IP Total Length (IPv4) or Payload Length > > (IPv6) field using this value, producing a malformed packet on the > > wire: the receiver interprets Ethernet padding bytes as IP payload. > > > > In practice this breaks protocol stacks that validate IP lengths > > strictly. A nested ESXi host running on OpenStack using the e1000e > > emulation sends short TCP ACK packets in response to a Windows guest's > > virtio TLS client hello, which get padded to 60 bytes; the inflated IP > > Total Length corrupts the IP header seen by Windows, causing TLS > > handshakes and TCP connections to fail. > > > > Fix net_tx_pkt_rebuild_payload() to read the IP header's declared > > length and clamp payload_len accordingly: > > > > IPv4: ip_total_len - l3_hdr_len > > IPv6: ip6_plen adjusted for parsed extension headers > > > > Guard both paths against malformed guest packets where the header- > > declared length is shorter than the IP header itself; without the > > guard the unsigned subtraction would underflow, producing a huge > > payload_len. Fall back to the raw iov_size() value in that case. > > This breaks net_tx_pkt_get_total_len(), which also uses payload_len and > expects pkt->hdr_len + pkt->payload_len produces the size of the entire > packet. It is also unclear whether fall back to the raw iov_size() makes > sense. I think we need to define what payload_len should represent to > figure out a correct solution.
See also this other recent thread about short packets: https://lore.kernel.org/qemu-devel/CAFEAcA_UhmCxJc16CHE=4ZR1+PA0=4-29=fee+d+iumhltz...@mail.gmail.com/ I'm not sure we're entirely clear and consistent about why and when we pad short packets (are we doing it to make our lives easier in writing the receive path in network device models? are we doing it because some net backends will hand us a 40 byte packet and a network device is entitled to expect a complete ethernet frame? other?). Do we need to distinguish (can we always?) the payload length and the padded length? I had a go at some patches that move the "pad this short packet" code around so we do it more consistently, but I don't feel very confident in them because I don't have an understanding of the overall requirements here yet. thanks -- PMM
