daemon: fix out-of-bounds read in dlt_daemon_control_set_log_level_v2 - #862
Closed
SoundMatt wants to merge 1 commit into
Closed
daemon: fix out-of-bounds read in dlt_daemon_control_set_log_level_v2#862SoundMatt wants to merge 1 commit into
SoundMatt wants to merge 1 commit into
Conversation
Mirror of COVESA#861 for the parallel SET_LOG_LEVEL V2 control handler. The fixed-size precheck validates only the 11-byte minimum SET_LOG_LEVEL V2 request (apidlen = ctidlen = 0). The function then reads two attacker- controlled uint8_t length fields (apidlen, ctidlen) and uses them to advance an offset into msg->databuffer, before passing pointers into the buffer to dlt_set_id_v2() (which reads up to apidlen / ctidlen bytes), a 1-byte log_level read, and a 4-byte memcpy of the trailing com field. A short message with non-zero length fields causes the variable-length reads to walk past the end of msg->databuffer. Add bounds checks after each length is parsed; on failure return without further processing (req is on the stack, no allocation cleanup required).
This was referenced May 5, 2026
SoundMatt
added a commit
to SoundMatt/dlt-daemon
that referenced
this pull request
Jun 18, 2026
Address review feedback on COVESA#864: instead of hand-parsing the wire buffer with a raw pointer assignment, copy the variable-length apid and ctid into local fixed-size buffers through the shared dlt_set_id_v2() helper, then point req.apid / req.ctid at those buffers. The original handler called dlt_set_id_v2(req.apid, ...) where req.apid is a NULL char * in the zero-initialised request struct, so the copy was a silent no-op that left req.apid / req.ctid NULL and crashed the daemon on the subsequent apid[apid_length - 1] dereference (COVESA#863, part of COVESA#866). Giving dlt_set_id_v2() a real destination keeps id initialisation inside the shared API (as requested in review) and avoids aliasing the receive buffer. Bounds validation of apidlen/ctidlen against datasize is handled separately in the set-log-level-v2 OOB-read fix (COVESA#862). Add unit tests for dlt_set_id_v2 (normal copy, cap/truncation at DLT_V2_ID_SIZE with overflow guard, and NULL/zero-length handling), which previously had no coverage. Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
|
Collaborator
|
This change is improperly applied. |
santhoshsivanhere
pushed a commit
to santhoshsivanhere/dlt-daemon
that referenced
this pull request
Jul 13, 2026
Correct APID and CTID parsing in dlt_daemon_control_set_log_level_v2(). The request structure stores APID and CTID as char * fields, but these pointers were never initialized before being passed to dlt_set_id_v2(). Since the helper returns immediately when given a NULL destination, the IDs were never parsed from the request, leaving req.apid and req.ctid NULL. Requests with empty APID/CTID fields silently became no-ops, while requests containing non-empty IDs could dereference a NULL pointer in the wildcard and field-only handling paths, crashing the daemon. Copy the APID and CTID into local fixed-size buffers using dlt_set_id_v2() and point req.apid and req.ctid at those buffers. This keeps ID initialization within the shared helper, avoids aliasing the receive buffer, and ensures the parsed IDs remain valid for the lifetime of the function. Also add unit tests covering dlt_set_id_v2() normal operation, truncation at DLT_V2_ID_SIZE, overflow handling, and NULL/zero-length inputs. Closes: COVESA#863 Related: COVESA#862 Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Santhosh Sivan Murugan <122221363+santhoshsivanhere@users.noreply.github.com>
santhoshsivanhere
pushed a commit
to santhoshsivanhere/dlt-daemon
that referenced
this pull request
Jul 13, 2026
Correct APID and CTID parsing in dlt_daemon_control_set_log_level_v2(). The request structure stores APID and CTID as char * fields, but these pointers were never initialized before being passed to dlt_set_id_v2(). Since the helper returns immediately when given a NULL destination, the IDs were never parsed from the request, leaving req.apid and req.ctid NULL. Requests with empty APID/CTID fields silently became no-ops, while requests containing non-empty IDs could dereference a NULL pointer in the wildcard and field-only handling paths, crashing the daemon. Copy the APID and CTID into local fixed-size buffers using dlt_set_id_v2() and point req.apid and req.ctid at those buffers. This keeps ID initialization within the shared helper, avoids aliasing the receive buffer, and ensures the parsed IDs remain valid for the lifetime of the function. Also add unit tests covering dlt_set_id_v2() normal operation, truncation at DLT_V2_ID_SIZE, overflow handling, and NULL/zero-length inputs. Closes: COVESA#863 Related: COVESA#862 Signed-off-by: Matt Jones <47545907+SoundMatt@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Santhosh Sivan Murugan <122221363+santhoshsivanhere@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Same shape as #861, applied to the parallel SET_LOG_LEVEL V2 handler.
dlt_daemon_control_set_log_level_v2validates only the 11-byte fixedportion of the SET_LOG_LEVEL V2 request before reading two attacker-
controlled
uint8_tlength fields (apidlen,ctidlen) and usingthem to advance a buffer offset. A short message with non-zero length
fields causes
dlt_set_id_v2(), the trailing 1-bytelog_levelread,and the final 4-byte
memcpy()of thecomfield to read past theend of
msg->databuffer. Reachable from any client that can talk tothe daemon's control socket. Bounded OOB read; no OOB write.
Fix
Two bounds checks:
apidlenis parsed, verify the message containsapidlen + 1more bytes (apid + the upcomingctidlenbyte).ctidlenis parsed, verify the message containsctidlen + 1 + DLT_ID_SIZEmore bytes (ctid + log_level + com).Unlike
dlt_daemon_control_get_log_info_v2in #861, the request structhere lives on the stack, so no allocation cleanup is required on the
early returns.
Notes
in either order.
function: at lines 3719/3721 the local
apid/ctidpointers(declared NULL at 3687/3688) are passed to
dlt_set_id_v2()whilestill NULL, so the call is a no-op, yet line 3723 (and later
branches) dereferences them:
apid[apid_length - 1]. This NULL-derefs whenever
apid_length != 0. Looks like the intent wasapid = req.apid;(pointer assignment). Filing separately sinceit's an orthogonal bug class.