Heap Buffer Overflow in dlt_message_read_v2()
- Dominant language
- C
- Stars
- 459
- Forks
- 340
- Avg merge
- 4d 21h
- Merged PRs (30d)
- 2
Description
## Summary
dlt_message_read_v2() calls dlt_message_get_extraparameters_from_recievedbuffer_v2() and dlt_message_get_extendedparameters_from_recievedbuffer_v2() before verifying that the input buffer contains the full header.
Neither parser receives the buffer length. The only pre-call check is:
```c
if (length < BASE_HEADER_V2_FIXED_SIZE) // 7 bytes only
return DLT_MESSAGE_ERROR_SIZE;
```
After the parsers run, the full-length check happens too late:
```c
if (length < (unsigned int)(msg->headersizev2 + msg->datasize))
return DLT_MESSAGE_ERROR_SIZE;
```
A crafted or truncated DLTv2 message can trigger out-of-bounds reads in the parser before the message is eventually rejected as incomplete.
## Vulnerable Code
```c
if (length < BASE_HEADER_V2_FIXED_SIZE)
return DLT_MESSAGE_ERROR_SIZE;
msg->baseheaderv2 = (DltBaseHeaderV2 *)buffer;
msgcontent = htyp2 & MSGCONTENT_MASK;
msg->baseheaderextrasizev2 =
dlt_message_get_extraparameters_size_v2(msgcontent);
dlt_message_get_extraparameters_from_recievedbuffer_v2(
msg, buffer, msgcontent);
dlt_message_get_extendedparameters_from_recievedbuffer_v2(
msg, buffer, msgcontent);
if (length < (unsigned int)(msg->headersizev2 + msg->datasize))
return DLT_MESSAGE_ERROR_SIZE;
```
## Root Cause
dlt-daemon in DLTv2 mode passes the raw TCP receiver buffer directly to dlt_message_read_v2():
```c
while (dlt_message_read_v2(&(daemon_local->msgv2),
(uint8_t *)receiver->buf,
(unsigned int) receiver->bytesRcvd,
...) == DLT_MESSAGE_ERROR_OK) {
```
The receiver buffer is allocated as calloc(10024):
```c
#define DLT_DAEMON_RCVBUFSIZESOCK 10024
```
A crafted DLTv2 TCP message that causes the extended parameter parser to advance its offset past bytesRcvd will trigger an out-of-bounds read from the receiver buffer.
## Reproduction Steps
A crafted DLTv2 message with many WTGS tags was sent to the daemon on TCP port 3490.
The daemon process was started with:
```bash
./dlt-daemon -x 2 -c dlt.conf
```
## Log
ASan report
```
==2562947==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x52600000e828 at pc 0x61625d2d9356 bp 0x7ffcbfffe3b0 sp 0x7ffcbfffdb70
READ of size 254 at 0x52600000e828 thread T0
#0 0x61625d2d9355 in __asan_memcpy (/root/dlt-daemon/latest/dlt-daemon+0x10d355) (BuildId: 27b9b5c2d7523d42651101a79aff9643ec011a07)
#1 0x61625d39a3b1 in dlt_message_get_extendedparameters_from_recievedbuffer_v2 /root/dlt-daemon/latest/code/src/shared/dlt_common.c
#2 0x61625d398b39 in dlt_message_read_v2 /root/dlt-daemon/latest/code/src/shared/dlt_common.c:1997:9
#3 0x61625d322c1b in dlt_daemon_process_client_messages /root/dlt-daemon/latest/code/src/daemon/dlt-daemon.c:3266:16
#4 0x61625d35dcc1 in dlt_daemon_handle_event /root/dlt-daemon/latest/code/src/daemon/dlt_daemon_event_handler.c:264:13
#5 0x61625d31dc10 in main /root/dlt-daemon/latest/code/src/daemon/dlt-daemon.c:1684:16
#6 0x7c25344611c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0x7c253446128a in __libc_start_main csu/../csu/libc-start.c:360:3
#8 0x61625d240654 in _start (/root/dlt-daemon/latest/dlt-daemon+0x74654) (BuildId: 27b9b5c2d7523d42651101a79aff9643ec011a07)
0x52600000e828 is located 0 bytes after 10024-byte region [0x52600000c100,0x52600000e828)
allocated by thread T0 here:
#0 0x61625d2db68d in calloc (/root/dlt-daemon/latest/dlt-daemon+0x10f68d) (BuildId: 27b9b5c2d7523d42651101a79aff9643ec011a07)
#1 0x61625d3a397e in dlt_receiver_init /root/dlt-daemon/latest/code/src/shared/dlt_common.c:3368:36
#2 0x61625d35ce4e in dlt_connection_get_receiver /root/dlt-daemon/latest/code/src/daemon/dlt_daemon_connection.c
#3 0x61625d35ce4e in dlt_connection_create /root/dlt-daemon/latest/code/src/daemon/dlt_daemon_connection.c:402:22
#4 0x61625d321cf2 in dlt_daemon_process_client_connect /root/dlt-daemon/latest/code/src/daemon/dlt-daemon.c:2960:13
#5 0x61625d35dcc1 in dlt_daemon_handle_event /root/dlt-daemon/latest/code/src/daemon/dlt_daemon_event_handler.c:264:13
#6 0x61625d31dc10 in main /root/dlt-daemon/latest/code/src/daemon/dlt-daemon.c:1684:16
#7 0x7c25344611c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#8 0x7c253446128a in __libc_start_main csu/../csu/libc-start.c:360:3
#9 0x61625d240654 in _start (/root/dlt-daemon/latest/dlt-daemon+0x74654) (BuildId: 27b9b5c2d7523d42651101a79aff9643ec011a07)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/root/dlt-daemon/latest/dlt-daemon+0x10d355) (BuildId: 27b9b5c2d7523d42651101a79aff9643ec011a07) in __asan_memcpy
Shadow bytes around the buggy address:
0x52600000e580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x52600000e600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x52600000e680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x52600000e700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x52600000e780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x52600000e800: 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa fa
0x52600000e880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x52600000e900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x52600000e980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x52600000ea00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x52600000ea80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==2562947==ABORTING
```
## Impact
```text
- Out-of-bounds Read
- Potential Information Disclosure
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in code/src/shared/dlt_common.c at dlt_message_read_v2() and the two DLTv2 parameter parsers, then review the call path in code/src/daemon/dlt-daemon.c. Reproduce with the described crafted TCP message under AddressSanitizer; done means truncated input is rejected without an out-of-bounds read and the existing valid-message path still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- networking, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100