From c6f65cb3a2e25b05df792e5f35a09878c65b38d4 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 26 Sep 2025 14:06:22 +0200 Subject: [PATCH] iosource/Packet: Allow ToRawPktHdrVal() for reassembled packets Closes #4845 --- src/iosource/Packet.cc | 6 +++++- .../output | 2 ++ testing/btest/Traces/ipv4/fragmented-syn.pcap | Bin 0 -> 164 bytes .../get_current_packet_header_fragmented_syn.zeek | 10 ++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/bifs.get_current_packet_header_fragmented_syn/output create mode 100644 testing/btest/Traces/ipv4/fragmented-syn.pcap create mode 100644 testing/btest/bifs/get_current_packet_header_fragmented_syn.zeek diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index c9d697334b..3f038a7115 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -144,7 +144,11 @@ RecordValPtr Packet::ToRawPktHdrVal() const { pkt_hdr->Assign(0, std::move(l2_hdr)); - if ( ip_hdr && cap_len >= ip_hdr->TotalLen() && (l3_proto == L3_IPV4 || l3_proto == L3_IPV6) ) + // The cap_len >= ip_hdr->TotalLen() and Reassembled() checks ensure that + // ToPktHdrVal() doesn't access out of bounds memory. For reassembled datagrams, + // cap_len ends up less than the reassembled packets total length. + if ( ip_hdr && (cap_len >= ip_hdr->TotalLen() || ip_hdr->Reassembled()) && + (l3_proto == L3_IPV4 || l3_proto == L3_IPV6) ) // Packet analysis will have stored the IP header in the packet, so we can use // that to build the output. return ip_hdr->ToPktHdrVal(std::move(pkt_hdr), 1); diff --git a/testing/btest/Baseline/bifs.get_current_packet_header_fragmented_syn/output b/testing/btest/Baseline/bifs.get_current_packet_header_fragmented_syn/output new file mode 100644 index 0000000000..11507dc7f1 --- /dev/null +++ b/testing/btest/Baseline/bifs.get_current_packet_header_fragmented_syn/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +[l2=[encap=LINK_ETHERNET, len=74, cap_len=50, src=98:ee:cb:bd:07:fe, dst=1e:0b:8b:14:f6:f9, vlan=, inner_vlan=, eth_type=2048, proto=L3_IPV4], ip=[hl=20, tos=0, len=60, id=1, DF=F, MF=T, offset=0, ttl=64, p=6, sum=36538, src=192.168.1.100, dst=10.0.0.5], ip6=, tcp=[sport=12345/tcp, dport=80/tcp, seq=1000, ack=0, hl=40, dl=0, reserved=0, flags=2, win=8192], udp=, icmp=] diff --git a/testing/btest/Traces/ipv4/fragmented-syn.pcap b/testing/btest/Traces/ipv4/fragmented-syn.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9637890edb4df4b92549125e4efc0967d8aad9ad GIT binary patch literal 164 zcmca|c+)~A1{MYw`2U}Qff2|t_1uv$mz9yh3djawIqq(eZ$D?eJH40v9|wag1A`6& zqXL5iTi>n&D;QI_7#LU$EExhA7?@uG6*DYgQeZe*%)r3J!ny@y(mkL_MnG{8#xO|* cXd$x$+q(TQlUSHIxES^%`hiShWM*au0Lf1#6#xJL literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/get_current_packet_header_fragmented_syn.zeek b/testing/btest/bifs/get_current_packet_header_fragmented_syn.zeek new file mode 100644 index 0000000000..da439c9deb --- /dev/null +++ b/testing/btest/bifs/get_current_packet_header_fragmented_syn.zeek @@ -0,0 +1,10 @@ +# @TEST-DOC: Regression test for #4845, get_current_packet_header() for a fragmented SYN packet +# +# @TEST-EXEC: zeek -b -C -r $TRACES/ipv4/fragmented-syn.pcap %INPUT >output +# @TEST-EXEC: btest-diff output + +event connection_SYN_packet(c: connection, pkt: SYN_packet) + { + local hdr: raw_pkt_hdr = get_current_packet_header(); + print fmt("%s", hdr); + }