Skip to content

Check incl_len against the file size in eaud_pcap_dissect() - #181

Open
arfa-21 wants to merge 1 commit into
sippy:masterfrom
arfa-21:eaud-pcap-incl-len
Open

arfa-21 wants to merge 1 commit into
sippy:masterfrom
arfa-21:eaud-pcap-incl-len

Conversation

@arfa-21

@arfa-21 arfa-21 commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Repro: cut tests/extractaudio/call1_g722_srtp.a.rtp down to its first record (264 bytes), set that record's incl_len to 0x10000000 and the RTP P bit, and run extractaudio <name> out.wav. It segfaults in rtp_packet_parse_raw() reading the padding length 256 MiB past the mapping (ASan: SEGV at rtp.c:318, called from load_pcap()).
Cause: eaud_pcap_dissect() takes incl_len from the record header and never compares it with the bytes left in the file, so load_pcap() passes a payload length that runs off the mmap()ed file to rtp_packet_parse_raw() and, when keys are given, to the in-place srtp_unprotect() in eaud_crypto_decrypt().
Fix: return PCP_DSCT_TRNK when incl_len doesn't fit, as eaud_adhoc_dissect() already does for adhoc recordings.

pcap_hdr_len is an int, so a non-IPv4 record with incl_len 0xfffffff0 wraps the record length to 0 and extractaudio -S spins on it forever on master. With the check it reports "broken or truncated PCAP file" and moves on. The same happens for a recording cut short in the middle of a record.

The new badargs sub-test builds the bad file from call1_g722_srtp with dd and expects exit status 1. It segfaults on master. Valid recordings are unaffected: scan output and the decoded mono/stereo WAVs for every tests/extractaudio fixture are byte-identical before and after. I built and ran this on macOS, where only extractaudio builds (rtpproxy itself doesn't), so the rest of the suite wasn't run locally.

eaud_pcap_dissect() derives the payload length and the offset of the
next record from the record's incl_len without checking it against the
bytes left in the file. load_pcap() then hands l5_data/l5_len to
rtp_packet_parse_raw(), and with SRTP to eaud_crypto_decrypt(), which
decrypts in place, so a record that claims more than the file holds is
read (or written) past the end of the mapping. A 264-byte recording
with incl_len 0x10000000 and the RTP P bit set makes extractaudio
segfault reading the padding length in rtp_packet_parse_raw().

pcap_hdr_len is an int, so an incl_len close to UINT32_MAX on a
non-IPv4 record also wraps the record length to 0 or a few bytes and
the scan loop stalls or resyncs in the middle of a record.

Return PCP_DSCT_TRNK for such records, the same way
eaud_adhoc_dissect() already handles truncated adhoc files.

Add a badargs sub-test that builds such a file from call1_g722_srtp
and expects extractaudio to fail with exit status 1 rather than crash.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant