Skip to content

Fix out-of-bounds reads in IcmpLayer getters on truncated packets - #2240

Open
Mrmaxmeier wants to merge 1 commit into
seladb:devfrom
Mrmaxmeier:fix/icmp-truncated-layer-oob
Open

Mrmaxmeier wants to merge 1 commit into
seladb:devfrom
Mrmaxmeier:fix/icmp-truncated-layer-oob

Conversation

@Mrmaxmeier

Copy link
Copy Markdown

Hi,

we ran into an out-of-bounds read ASAN report with the FuzzTarget.cpp harness:

==18==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b90f7df0539 at pc 0x561cdbc3ca9f bp 0x7ffd35723b70 sp 0x7ffd35723b68
READ of size 2 at 0x7b90f7df0539 thread T0
SCARINESS: 14 (2-byte-read-heap-buffer-overflow)
    #0 0x561cdbc3ca9e in readParsedPacket(pcpp::Packet, pcpp::Layer*) /src/PcapPlusPlus/Tests/Fuzzers/ReadParsedPacket.h:357:61
    #1 0x561cdbc3691c in LLVMFuzzerTestOneInput /src/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:66:5

DEDUP_TOKEN: readParsedPacket(pcpp::Packet, pcpp::Layer*)--LLVMFuzzerTestOneInput--fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long)
0x7b90f7df0539 is located 0 bytes after 41-byte region [0x7b90f7df0510,0x7b90f7df0539)
allocated by thread T0 here:
    #0 0x561cdbc3461d in operator new[](unsigned long) /src/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:111:37
    #1 0x561cdbc4f820 in make_unique<unsigned char[], 0> /usr/local/bin/../include/c++/v1/__memory/unique_ptr.h:765:55
    #2 0x561cdbc4f820 in pcpp::PcapFileReaderDevice::getNextPacket(pcpp::RawPacket&) /src/PcapPlusPlus/Pcap++/src/PcapFileDevice.cpp:780:23
    #3 0x561cdbc36a14 in LLVMFuzzerTestOneInput /src/PcapPlusPlus/Tests/Fuzzers/FuzzTarget.cpp:71:19

The input is included in this PR under Tests/Fuzzers/RegressionTests/regression_samples/crash-icmp-info-request-truncated.

The getX() methods in IcmpLayer.h currently only check the type field, and return a casted struct without verifying that the underlying buffer has enough data. This PR adjusts these getters to return nullptr in the case of packets without enough data. It also adds a test that verifies this behaviour for various ICMP message types.

Thanks!


Found by the CISPA Fandango team while triaging findings in oss-fuzz harnesses.

@Mrmaxmeier
Mrmaxmeier requested a review from seladb as a code owner August 27, 2026 14:41
@Mrmaxmeier Mrmaxmeier changed the title Fix out-of-bounds reads in IcmpLayer message getters on truncated pac… Fix out-of-bounds reads in IcmpLayer getters on truncated packets Aug 27, 2026
@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.77%. Comparing base (52695e4) to head (62ff66d).
⚠️ Report is 2 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2240      +/-   ##
==========================================
+ Coverage   82.73%   82.77%   +0.03%     
==========================================
  Files         333      333              
  Lines       60372    60407      +35     
  Branches    12866    12880      +14     
==========================================
+ Hits        49947    50000      +53     
+ Misses       9549     9531      -18     
  Partials      876      876              
Flag Coverage Δ
23.11.6 7.24% <1.28%> (-0.05%) ⬇️
24.11.5 7.22% <1.28%> (-0.07%) ⬇️
25.11.1 7.27% <1.28%> (-0.01%) ⬇️
alpine320 76.97% <93.75%> (+0.06%) ⬆️
fedora42 76.52% <95.83%> (+0.03%) ⬆️
macos-15 82.35% <97.70%> (+0.05%) ⬆️
macos-26 82.36% <97.70%> (+0.06%) ⬆️
macos-26-intel 82.29% <97.70%> (+0.05%) ⬆️
mingw32 71.60% <83.33%> (+0.04%) ⬆️
mingw64 71.56% <83.33%> (+0.11%) ⬆️
npcap ?
rhel94 76.35% <94.00%> (+0.05%) ⬆️
ubuntu2204 76.36% <94.00%> (+0.03%) ⬆️
ubuntu2404 76.67% <93.75%> (+0.07%) ⬆️
ubuntu2604 76.62% <95.83%> (+0.04%) ⬆️
ubuntu2604-arm64 76.44% <95.74%> (+0.05%) ⬆️
ubuntu2604-icpx 59.22% <95.12%> (+0.07%) ⬆️
unittest 82.77% <100.00%> (+0.03%) ⬆️
windows-2022 85.88% <100.00%> (+0.15%) ⬆️
windows-2025 85.62% <100.00%> (+0.17%) ⬆️
winpcap 85.91% <100.00%> (+0.25%) ⬆️
xdp 53.48% <93.75%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Mrmaxmeier
Mrmaxmeier force-pushed the fix/icmp-truncated-layer-oob branch from 71f0a41 to 1316e19 Compare August 27, 2026 22:00
Comment thread Tests/Packet++Test/Tests/IcmpTests.cpp Outdated
Every get*Data() method checked only the ICMP message type before casting
the layer buffer to the fixed-size structure that type implies, so a
truncated capture produced an IcmpLayer shorter than the structure it
claims to be and reading any field past the layer was out of bounds.

Route those getters through a castMessageData() helper that requires the
whole structure to be present, and tighten isDataValid() accordingly.

Assisted-By: Claude Opus 5 <noreply@anthropic.com>
@Mrmaxmeier
Mrmaxmeier force-pushed the fix/icmp-truncated-layer-oob branch from 1316e19 to 62ff66d Compare September 5, 2026 08:19
/// a timestamp of when the message was sent. Not part of the RFC 792 echo header, these are the first 8
/// bytes of the echo payload, and they are absent from a message shorter than sizeof(icmp_echo_hdr)
uint64_t timestamp;
} icmp_echo_hdr;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that timestamp isn't part of the RFC. In that case we might need a breaking change here:

  • Remove timestamp from the struct (that way we no longer need ICMP_ECHO_MIN_LEN)
  • Add 2 methods to icmp_echo_request that returns the timestamp if exists:
    • bool hasTimestamp()
    • uint64_t getTimetamp()

// ICMP_INFO_REQUEST, ICMP_INFO_REPLY
if (type == 15 || type == 16)
return dataLen >= sizeof(icmp_info_request);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, this is the only change that is related to the PR description. The other changes are separate. Maybe we can break this PR to multiple PRs?

  • The first contains only this change (and tests)
  • Another PR for making timestamp optional in echo request (and tests)
  • A last PR for fixing getRouterAddress() (if you prefer to open less PRs, you can include it in the second PR because it's pretty minor change

@@ -0,0 +1 @@
86bc7fd77f154090c5725840080045000027b8b10000400100000a000036c00f0f0f0f0f0f0f0f0f0f No newline at end of file

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you include the pcap file for this packet? That way it'd be easier to view it in Wireshark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants