Security vulnerability report: AUTOSAR Dcm_Dsp integer overflow in DTC response handlers
Identification
- Product: autoas/as — open source AUTOSAR Basic Software implementation
- Repository: https://github.com/autoas/as
- Component:
infras/diagnostic/Dcm/Dcm_Dsp.c, DTC reporting functions
- Reporter: Vito Rallo, Peach Studio (me@vitorallo.com)
- Discovery method: Automated security review using foil with securereview-systems-v2 model
- Date discovered: 2026-05-03
Summary
Three functions in the AUTOSAR Diagnostic Communication Manager
(DCM) compute response buffer sizes using the expression
NumberOfFilteredDTC * 4 + 2 (or * 4 + 1) where
NumberOfFilteredDTC is uint16_t. On 16-bit microcontrollers
(where int is 16 bits), this multiplication overflows when the
DTC count reaches 16384, wrapping the computed size to a small
value. The subsequent bounds check passes with the wrapped value,
and a loop writes NumberOfFilteredDTC * 4 bytes into the response
buffer — a stack or heap buffer overflow.
Severity
- CVSS v3.1 Base Score: 7.5 (High) on 16-bit MCU targets
- Vector: AV:A/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
- Attack Vector: Adjacent (CAN bus / OBD-II port)
- Attack Complexity: High (requires DTC count >= 16384)
Not affected: 32-bit MCUs (ARM Cortex-M, RH850, AURIX) where
int is 32 bits. C99 integer promotion widens uint16_t to int
before the multiplication, and 65535 * 4 + 2 = 262142 fits in
32-bit int.
Affected: 16-bit MCUs where int is 16 bits:
- Renesas RL78 (body controllers, seat modules, climate control)
- NXP/Freescale S12X (instrument clusters, body control modules)
- Infineon C166 (older ECUs)
- Microchip PIC24 (sensor modules)
Affected code (3 instances)
Instance 1: Dem_DspReportDTCByStatusMask (line 1186)
uint16_t NumberOfFilteredDTC = 0;
// ...
r = Dem_GetNumberOfFilteredDTC(0, &NumberOfFilteredDTC);
// ...
if ((NumberOfFilteredDTC * 4 + 2) <= msgContext->resMaxDataLen) {
// Bounds check PASSES with overflowed value
for (i = 0; (i < NumberOfFilteredDTC) && (E_OK == r); i++) {
// Loop iterates NumberOfFilteredDTC times
msgContext->resData[2 + 4 * i] = ...; // OVERFLOW
msgContext->resData[3 + 4 * i] = ...;
msgContext->resData[4 + 4 * i] = ...;
msgContext->resData[5 + 4 * i] = ...;
}
}
UDS Service 0x19, SubFunction 0x02 (ReportDTCByStatusMask).
Instance 2: Dem_DspReportDTCSnapshotIdentification (line 1245)
if ((NumberOfFilteredRecords * 4 + 1) <= msgContext->resMaxDataLen) {
for (i = 0; (i < NumberOfFilteredRecords) && (E_OK == r); i++) {
msgContext->resData[1 + 4 * i] = ...; // OVERFLOW
UDS Service 0x19, SubFunction 0x03 (ReportDTCSnapshotIdentification).
Instance 3: Line 1401
Same pattern, different DTC reporting sub-service.
Integer overflow mechanics
On a 16-bit MCU, uint16_t * 4 is computed in 16-bit unsigned
arithmetic. The multiplication wraps at 65536:
| NumberOfFilteredDTC |
n * 4 + 2 (uint16) |
Passes check? |
Bytes written |
| 100 |
402 |
Depends on resMaxDataLen |
400 |
| 1000 |
4002 |
Depends |
4000 |
| 16383 |
65534 |
No (too big) |
— |
| 16384 |
2 |
Yes |
65536 |
| 16385 |
6 |
Yes |
65540 |
| 32768 |
2 |
Yes |
131072 |
When NumberOfFilteredDTC = 16384:
16384 * 4 + 2 = 65538 wraps to 2 in uint16
- Check:
2 <= resMaxDataLen → passes (resMaxDataLen is typically 4095)
- Loop iterates 16384 times, writing
16384 * 4 = 65536 bytes
resData buffer is typically 4095 bytes → 61441 bytes overflow
Exploitability analysis
Can NumberOfFilteredDTC reach 16384?
Dem_GetNumberOfFilteredDTC() returns the count of DTCs matching a
status filter from the DTC storage (flash/EEPROM). Typical production
ECUs have 256-4096 DTC entries — too few to trigger the overflow.
However:
- Development/calibration builds may have larger DTC tables
- DTC storage corruption (e.g., from voltage glitch or flash
wear) could cause Dem_GetNumberOfFilteredDTC to return an
incorrect high value
- Dem implementation bugs in the count calculation could return
values > 16384 even with fewer actual entries
- The
autoas/as Dem implementation (infras/diagnostic/Dem/) may
not cap the returned count
Attack scenario
- Attacker connects to OBD-II port (physical access required:
mechanic, parking valet, rental car, stolen vehicle, charging
station for EVs)
- Attacker sends UDS requests to manipulate DTC storage (if write
access is available without security authentication)
- Attacker sends UDS 0x19/0x02 (ReadDTCByStatusMask) with
statusMask = 0xFF (match all)
- If DTC count >= 16384, the response calculation overflows
- The response write loop overwrites the stack past
resData
- On 16-bit MCU without stack protection: attacker controls the
return address → code execution on the ECU
- Compromised ECU sends arbitrary CAN messages to other ECUs on
the bus (braking, steering, engine, transmission)
Why this is still reportable despite limited triggering
-
The code pattern is wrong regardless of triggering. The
multiplication can overflow and the bounds check is defeated.
MISRA-C Rule 12.11 requires checking for overflow before
arithmetic operations. This is a MISRA violation.
-
The same pattern likely exists in commercial AUTOSAR stacks.
The AUTOSAR specification defines the DTC response format, and
many implementations follow the same nDTC * 4 + header size
calculation. If a commercial stack (Vector, ETAS, EB) uses the
same code pattern on 16-bit MCUs, the impact is much larger.
-
Defense in depth. Even if the DTC count can't reach 16384
today, a future configuration change, Dem bug, or storage
corruption could expose the overflow. The fix is simple and
eliminates the risk.
Suggested fix
Add overflow check before the bounds comparison:
uint32_t responseSize = (uint32_t)NumberOfFilteredDTC * 4u + 2u;
if (responseSize <= msgContext->resMaxDataLen) {
// ... safe to proceed
}
Casting to uint32_t before the multiplication ensures the
arithmetic is done in 32 bits regardless of MCU word size.
Alternatively, cap NumberOfFilteredDTC to a safe maximum:
#define DCM_MAX_REPORTABLE_DTCS ((resMaxDataLen - 2) / 4)
if (NumberOfFilteredDTC > DCM_MAX_REPORTABLE_DTCS) {
*nrc = DCM_E_RESPONSE_TOO_LONG;
return E_NOT_OK;
}
Proof of concept
A traditional PoC is not feasible because:
- AUTOSAR runs on bare-metal MCUs, not under Linux/QEMU
- The overflow requires a 16-bit MCU target (RL78, S12X)
- NumberOfFilteredDTC must reach 16384 (requires DTC storage
manipulation or Dem bug)
Static analysis confirmation: The vulnerability is confirmed by
source code analysis. The uint16_t type of NumberOfFilteredDTC
and the 16-bit multiplication overflow are verifiable from the
source without runtime testing.
MISRA-C compliance check: The code violates MISRA-C:2012
Rule 12.11 (evaluation of constant unsigned integer expressions
should not lead to wrap-around). Any MISRA-compliant static
analysis tool (Polyspace, LDRA, Parasoft) would flag this pattern.
Credit
Discovered by Vito Rallo (Peach Studio) using foil, an AI-powered
security code scanner, with the securereview-systems-v2 model
trained on C/C++ vulnerability patterns which I am not yet making
available to the community (foil.peachstudio.be). I am assessing the
potential and impact of such model public available.
If you need to get access in preliminary, controlled group, let me know.
Security vulnerability report: AUTOSAR Dcm_Dsp integer overflow in DTC response handlers
Identification
infras/diagnostic/Dcm/Dcm_Dsp.c, DTC reporting functionsSummary
Three functions in the AUTOSAR Diagnostic Communication Manager
(DCM) compute response buffer sizes using the expression
NumberOfFilteredDTC * 4 + 2(or* 4 + 1) whereNumberOfFilteredDTCisuint16_t. On 16-bit microcontrollers(where
intis 16 bits), this multiplication overflows when theDTC count reaches 16384, wrapping the computed size to a small
value. The subsequent bounds check passes with the wrapped value,
and a loop writes
NumberOfFilteredDTC * 4bytes into the responsebuffer — a stack or heap buffer overflow.
Severity
Not affected: 32-bit MCUs (ARM Cortex-M, RH850, AURIX) where
intis 32 bits. C99 integer promotion widensuint16_ttointbefore the multiplication, and
65535 * 4 + 2 = 262142fits in32-bit
int.Affected: 16-bit MCUs where
intis 16 bits:Affected code (3 instances)
Instance 1: Dem_DspReportDTCByStatusMask (line 1186)
UDS Service 0x19, SubFunction 0x02 (ReportDTCByStatusMask).
Instance 2: Dem_DspReportDTCSnapshotIdentification (line 1245)
UDS Service 0x19, SubFunction 0x03 (ReportDTCSnapshotIdentification).
Instance 3: Line 1401
Same pattern, different DTC reporting sub-service.
Integer overflow mechanics
On a 16-bit MCU,
uint16_t * 4is computed in 16-bit unsignedarithmetic. The multiplication wraps at 65536:
When
NumberOfFilteredDTC = 16384:16384 * 4 + 2 = 65538wraps to2in uint162 <= resMaxDataLen→ passes (resMaxDataLen is typically 4095)16384 * 4 = 65536bytesresDatabuffer is typically 4095 bytes → 61441 bytes overflowExploitability analysis
Can NumberOfFilteredDTC reach 16384?
Dem_GetNumberOfFilteredDTC()returns the count of DTCs matching astatus filter from the DTC storage (flash/EEPROM). Typical production
ECUs have 256-4096 DTC entries — too few to trigger the overflow.
However:
wear) could cause
Dem_GetNumberOfFilteredDTCto return anincorrect high value
values > 16384 even with fewer actual entries
autoas/asDem implementation (infras/diagnostic/Dem/) maynot cap the returned count
Attack scenario
mechanic, parking valet, rental car, stolen vehicle, charging
station for EVs)
access is available without security authentication)
statusMask = 0xFF (match all)
resDatareturn address → code execution on the ECU
the bus (braking, steering, engine, transmission)
Why this is still reportable despite limited triggering
The code pattern is wrong regardless of triggering. The
multiplication can overflow and the bounds check is defeated.
MISRA-C Rule 12.11 requires checking for overflow before
arithmetic operations. This is a MISRA violation.
The same pattern likely exists in commercial AUTOSAR stacks.
The AUTOSAR specification defines the DTC response format, and
many implementations follow the same
nDTC * 4 + headersizecalculation. If a commercial stack (Vector, ETAS, EB) uses the
same code pattern on 16-bit MCUs, the impact is much larger.
Defense in depth. Even if the DTC count can't reach 16384
today, a future configuration change, Dem bug, or storage
corruption could expose the overflow. The fix is simple and
eliminates the risk.
Suggested fix
Add overflow check before the bounds comparison:
Casting to
uint32_tbefore the multiplication ensures thearithmetic is done in 32 bits regardless of MCU word size.
Alternatively, cap
NumberOfFilteredDTCto a safe maximum:Proof of concept
A traditional PoC is not feasible because:
manipulation or Dem bug)
Static analysis confirmation: The vulnerability is confirmed by
source code analysis. The
uint16_ttype ofNumberOfFilteredDTCand the 16-bit multiplication overflow are verifiable from the
source without runtime testing.
MISRA-C compliance check: The code violates MISRA-C:2012
Rule 12.11 (evaluation of constant unsigned integer expressions
should not lead to wrap-around). Any MISRA-compliant static
analysis tool (Polyspace, LDRA, Parasoft) would flag this pattern.
Credit
Discovered by Vito Rallo (Peach Studio) using foil, an AI-powered
security code scanner, with the securereview-systems-v2 model
trained on C/C++ vulnerability patterns which I am not yet making
available to the community (foil.peachstudio.be). I am assessing the
potential and impact of such model public available.
If you need to get access in preliminary, controlled group, let me know.