Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix vuln OSV-2024-382 #1698

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open

Fix vuln OSV-2024-382 #1698

wants to merge 3 commits into from

Conversation

aled-ua
Copy link
Contributor

@aled-ua aled-ua commented Jan 23, 2025

[Warning] This PR is generated by AI

Pull Request Description


  1. PR Title: Fix for Vulnerability in PcapPlusPlus - OSV-2024-382

  2. PR Description:

    • Bug Type: Heap-buffer-overflow
    • Summary: A vulnerability was identified in the PcapPlusPlus library, specifically in the UdpLayer class, where functions were accessing data beyond the bounds of the allocated buffer. This occurred when the buffer size was insufficient for operations involving UDP header fields, leading to a heap-buffer-overflow. The issue was reported in the OSV-2024-382 vulnerability report.
    • Fix Summary: The patch fixes the issue by introducing bounds checks in the following functions:
      • getSrcPort(): Ensures that the buffer length is sufficient before accessing the source port.
      • getDstPort(): Ensures that the buffer length is sufficient before accessing the destination port.
      • computeCalculateFields(): Ensures that the buffer length is sufficient before performing length and checksum calculations.
        These changes ensure that unsafe memory access is avoided, improving both the security and stability of the program.
  3. Sanitizer Report Summary:

    • The sanitizer detected a heap-buffer-overflow where the program attempted to read 2 bytes beyond the allocated buffer of size 61. The issue occurred in the UdpLayer class while accessing UDP header fields. The root cause was the lack of bounds checking before accessing these fields, leading to out-of-bounds memory access.
  4. Full Sanitizer Report:

    ==87957==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50600000905d at pc 0x55fb99be6e54 bp 0x7fff22d09870 sp 0x7fff22d09868
    READ of size 2 at 0x50600000905d thread T0
        #0 0x55fb99be6e53 in pcpp::UdpLayer::getSrcPort() const /root/Packet++/src/UdpLayer.cpp:40:10
        #1 0x55fb99be9499 in pcpp::UdpLayer::toString[abi:cxx11]() const /root/Packet++/src/UdpLayer.cpp:161:20
        #2 0x55fb99b6c917 in pcpp::Packet::toStringList(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, bool) const /root/Packet++/src/Packet.cpp:833:31
        #3 0x55fb99b6c527 in pcpp::Packet::toString[abi:cxx11](bool) const /root/Packet++/src/Packet.cpp:821:3
        #4 0x55fb99aafce6 in LLVMFuzzerTestOneInput /root/Tests/Fuzzers/FuzzTarget.cpp:60:17
        #5 0x55fb999ba6d4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/out/FuzzTarget+0xd66d4) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #6 0x55fb999a3806 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/root/out/FuzzTarget+0xbf806) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #7 0x55fb999a92ba in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/root/out/FuzzTarget+0xc52ba) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #8 0x55fb999d3a76 in main (/root/out/FuzzTarget+0xefa76) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #9 0x7f7a7f0ea1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #10 0x7f7a7f0ea28a in __libc_start_main csu/../csu/libc-start.c:360:3
        #11 0x55fb9999e3d4 in _start (/root/out/FuzzTarget+0xba3d4) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
    
    0x50600000905d is located 0 bytes after 61-byte region [0x506000009020,0x50600000905d)
    allocated by thread T0 here:
        #0 0x55fb99aacf21 in operator new[](unsigned long) (/root/out/FuzzTarget+0x1c8f21) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #1 0x55fb99aca8c6 in pcpp::PcapFileReaderDevice::getNextPacket(pcpp::RawPacket&) /root/Pcap++/src/PcapFileDevice.cpp:338:28
        #2 0x55fb99ac7e3f in pcpp::IFileReaderDevice::getNextPackets(pcpp::PointerVector<pcpp::RawPacket>&, int) /root/Pcap++/src/PcapFileDevice.cpp:117:22
        #3 0x55fb99aafbf4 in LLVMFuzzerTestOneInput /root/Tests/Fuzzers/FuzzTarget.cpp:46:14
        #4 0x55fb999ba6d4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/root/out/FuzzTarget+0xd66d4) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #5 0x55fb999a3806 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (/root/out/FuzzTarget+0xbf806) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #6 0x55fb999a92ba in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/root/out/FuzzTarget+0xc52ba) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #7 0x55fb999d3a76 in main (/root/out/FuzzTarget+0xefa76) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
        #8 0x7f7a7f0ea1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
        #9 0x7f7a7f0ea28a in __libc_start_main csu/../csu/libc-start.c:360:3
        #10 0x55fb9999e3d4 in _start (/root/out/FuzzTarget+0xba3d4) (BuildId: f3b6f7ff5942f35185d0681a33ca22744978264a)
    
    SUMMARY: AddressSanitizer
    
  5. Files Modified:

    • Packet++/src/UdpLayer.cpp
    diff --git a/Packet++/src/UdpLayer.cpp b/Packet++/src/UdpLayer.cpp
    index 9cfaa2cb..5158793d 100644
    --- a/Packet++/src/UdpLayer.cpp
    +++ b/Packet++/src/UdpLayer.cpp
    @@ -37,11 +37,19 @@ namespace pcpp
    
    	uint16_t UdpLayer::getSrcPort() const
    	{
    +		if (m_DataLen < sizeof(udphdr)) {
    +			PCPP_LOG_ERROR("Buffer too small to access source port");
    +			return 0; // Return an invalid port number
    +		}
    		return be16toh(getUdpHeader()->portSrc);
    	}
    
    	uint16_t UdpLayer::getDstPort() const
    	{
    +		if (m_DataLen < sizeof(udphdr)) {
    +			PCPP_LOG_ERROR("Buffer too small to access destination port");
    +			return 0; // Return an invalid port number
    +		}
    		return be16toh(getUdpHeader()->portDst);
    	}
    
    @@ -151,6 +159,10 @@ namespace pcpp
    	void UdpLayer::computeCalculateFields()
    	{
    		udphdr* udpHdr = (udphdr*)m_Data;
    +		if (m_DataLen < sizeof(udphdr)) {
    +			PCPP_LOG_ERROR("Buffer too small to calculate fields");
    +			return;
    +		}
    		udpHdr->length = htobe16(m_DataLen);
    		calculateChecksum(true);
    	}
  6. Patch Validation: The patch has been validated and confirmed to resolve the issue identified in the sanitizer report. No new bugs were introduced.

  7. Links:

    • PoC Binary

@aled-ua aled-ua requested a review from seladb as a code owner January 23, 2025 09:40
Copy link

codecov bot commented Jan 23, 2025

Codecov Report

Attention: Patch coverage is 33.33333% with 6 lines in your changes missing coverage. Please review.

Project coverage is 83.09%. Comparing base (f81ced2) to head (ac92d06).
Report is 17 commits behind head on dev.

Files with missing lines Patch % Lines
Packet++/src/UdpLayer.cpp 33.33% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1698      +/-   ##
==========================================
- Coverage   83.16%   83.09%   -0.08%     
==========================================
  Files         277      277              
  Lines       48193    48210      +17     
  Branches     9966    10161     +195     
==========================================
- Hits        40081    40060      -21     
- Misses       7234     7263      +29     
- Partials      878      887       +9     
Flag Coverage Δ
alpine320 75.05% <0.00%> (-0.11%) ⬇️
fedora40 75.11% <0.00%> (-0.09%) ⬇️
macos-13 80.59% <0.00%> (-0.07%) ⬇️
macos-14 80.60% <0.00%> (-0.07%) ⬇️
macos-15 80.57% <0.00%> (-0.07%) ⬇️
mingw32 70.78% <0.00%> (-0.14%) ⬇️
mingw64 70.74% <0.00%> (-0.14%) ⬇️
npcap 85.14% <33.33%> (-0.18%) ⬇️
rhel94 74.94% <0.00%> (-0.09%) ⬇️
ubuntu2004 58.53% <0.00%> (-0.10%) ⬇️
ubuntu2004-zstd 58.65% <0.00%> (-0.10%) ⬇️
ubuntu2204 74.86% <0.00%> (-0.12%) ⬇️
ubuntu2204-icpx 61.41% <0.00%> (-0.03%) ⬇️
ubuntu2404 75.11% <0.00%> (-0.09%) ⬇️
unittest 83.09% <33.33%> (-0.08%) ⬇️
windows-2019 85.24% <33.33%> (-0.11%) ⬇️
windows-2022 85.27% <33.33%> (-0.11%) ⬇️
winpcap 85.24% <33.33%> (-0.10%) ⬇️
xdp 50.51% <0.00%> (-0.02%) ⬇️

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

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

@@ -151,6 +161,11 @@ namespace pcpp
void UdpLayer::computeCalculateFields()
{
udphdr* udpHdr = (udphdr*)m_Data;
if (m_DataLen < sizeof(udphdr))
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's move this line at the beginning.

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.

2 participants