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 The first ingredient 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 ingredient was letting it overshoot the stop byte (0xFF). This can be attributed to lack of control of its placement relative to the end of the serialized stream, let alone the end of the buffer: The stop byte was at the end of the buffer, but 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). It tempts me to introduce some helper functions to help with consistency (not to mention collapsing repeated lines 8-fold). 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. Whether to add a functioning stop byte does not matter. It is trivial to add a check that the serialized stream ends at the end of the buffer. 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