COVESA / COVESA/dlt-daemon

Heap Buffer Overflow in dlt_message_read_v2()

Open
#894 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.