Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unit-test of DHCP option parser: Delete the buffer overflow
Symptom: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffc9dfa5c07 READ of size 1 at 0x7ffc9dfa5c07 thread T0 #0 0x459a49 in prvProcessDHCPReplies test/unit-test/build/Annexed_TCP_Sources/FreeRTOS_DHCP.c:1310 FreeRTOS#1 0x4526d2 in vHandleWaitingAcknowledge test/unit-test/build/Annexed_TCP_Sources/FreeRTOS_DHCP.c:495 FreeRTOS#2 0x4544ef in vDHCPProcessEndPoint test/unit-test/build/Annexed_TCP_Sources/FreeRTOS_DHCP.c:739 FreeRTOS#3 0x43dbd9 in test_vDHCPProcess_eWaitingAcknowledge_DNSIncorrectLength2 (test/unit-test/build/bin/tests/FreeRTOS_DHCP_utest+0x43dbd9) Address 0x7ffc9dfa5c07 is located in stack of thread T0 SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow test/unit-test/build/Annexed_TCP_Sources/FreeRTOS_DHCP.c:1310 in prvProcessDHCPReplies Shadow bytes around the buggy address: 0x7ffc9dfa5980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5a80: 00 00 00 00 00 00 00 00 ca ca ca ca 00 00 00 00 0x7ffc9dfa5b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7ffc9dfa5c00:[05]cb cb cb cb cb cb cb 00 00 00 00 00 00 00 00 0x7ffc9dfa5c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ffc9dfa5e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Left alloca redzone: ca Right alloca redzone: cb There were two problems that conspired to create this segfault. The first was allowing the option parser to run off the end of the buffer at all: /* ulGenericLength is incremented by 100 to have uxDNSCount > ipconfigENDPOINT_DNS_ADDRESS_COUNT scenario */ ulGenericLength = sizeof( DHCPMsg ) + 100; The second problem was letting it overshoot the stop byte (0xFF). Which is a problem with having manually updated indexes and length fields. The stop byte was at the end of the buffer, but was of no help, because the buffer length was off by -3 (missing 2 bytes for the opcode and length field of the 6 server addresses and 1 byte to account for an unexplained hole in the serialized stream). The real fix for this kind of fragility is using some helper funcitons for serializing the data while keeping indexes and lenghts consistent (not to mention collapsing repeated lines 8-fold). Anyway, it is trivial to add a check that the serialized stream ends at the end of the buffer (done). Whether to add a functioning stop byte does not matter and should not be needed anymore with such a check. I initially fixed it the wrong way, by keeping it within the same buffer, which hurt line coverage. But what the test wants to test is as commented: At least 6 server addresses, because that's the value of ipconfigENDPOINT_DNS_ADDRESS_COUNT + 1. No "invalid" length required, just an overabundance of DNS servers. As such, let's rename the test. Btw, the test was using a VLA (fixed), and most of the uint32_t writes are still unaligned (I replaced one of them with memcpy).
- Loading branch information