Skip to content

Heap Buffer Overflow in dlt_message_read_v2() #894

Description

@cryptcrack

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:

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:

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

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():

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):

#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:

./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

- Out-of-bounds Read
- Potential Information Disclosure

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions