Skip to main content
Vulnerability Database/CVE-2026-18413

CVE-2026-18413: Zephyr MCUX LPADC Privilege Escalation

CVE-2026-18413 is a privilege escalation flaw in Zephyr RTOS MCUX LPADC driver that allows unprivileged threads to corrupt kernel memory. This post explains its technical details, affected versions, and mitigation steps.

Published:

CVE-2026-18413 Overview

CVE-2026-18413 is an out-of-bounds write vulnerability [CWE-787] in the Zephyr RTOS NXP MCUX LPADC driver. The driver function mcux_lpadc_start_read() in drivers/adc/adc_mcux_lpadc.c fails to validate that the caller-supplied destination buffer is large enough to hold the requested samples. Each completed analog-to-digital conversion writes a 16-bit sample through an unbounded pointer in either mcux_lpadc_isr() or mcux_lpadc_dma_callback(). On builds with CONFIG_USERSPACE, an unprivileged user-mode thread with access to an LPADC device can direct kernel-mode writes into arbitrary adjacent memory.

Critical Impact

A user-mode thread can trigger up to channels * 65536 samples into a buffer as small as two bytes, corrupting kernel data, thread stacks, or other memory partitions from an unprivileged context.

Affected Products

  • Zephyr RTOS builds using the NXP MCUX LPADC driver (drivers/adc/adc_mcux_lpadc.c)
  • Zephyr RTOS builds using the ADI MAX32 ADC driver (drivers/adc/adc_max32.c)
  • Builds with CONFIG_USERSPACE enabled are affected by privilege escalation; other builds are affected as a robustness defect

Discovery Timeline

  • 2026-09-28 - CVE-2026-18413 published to NVD
  • 2026-09-30 - Last updated in NVD database

Technical Details for CVE-2026-18413

Vulnerability Analysis

The Zephyr ADC API contract in include/zephyr/drivers/adc.h requires drivers to reject any sampling sequence whose destination buffer is too small. The buffer_size field of struct adc_sequence documents that the driver must return an error when the buffer cannot hold the requested samples. The NXP MCUX LPADC driver did not enforce this contract.

mcux_lpadc_start_read() assigned data->buffer = sequence->buffer without any size check. Each conversion then wrote one 16-bit sample per enabled channel through *data->buffer++, walking linearly past the buffer end. The sample pointer is only rewound on a repeat sampling, not on the extra samplings of a sequence, so an attacker controlling options->extra_samplings can generate a very large write.

Root Cause

The root cause is missing input validation of the buffer_size field before starting the ADC sampling sequence. On CONFIG_USERSPACE builds, the syscall handler in drivers/adc/adc_handlers.c verifies only that [buffer, buffer + buffer_size) is writable by the caller; it deliberately defers size arithmetic to the driver. Because the driver skipped that arithmetic, a user-mode caller fully controls channels, buffer, buffer_size, and options->extra_samplings.

Attack Vector

A local user-mode thread granted access to an LPADC device object submits an adc_read() or adc_read_async() call with a small buffer and a sequence selecting multiple channels with a large extra_samplings value. The out-of-bounds stores execute in kernel mode from the ADC interrupt handler or DMA completion callback, where the MPU does not enforce the calling thread's memory domain. The result is a write primitive of attacker-chosen length at an attacker-chosen offset into kernel data or adjacent thread stacks.

c
// Fix: shared buffer validation helper added in drivers/adc/adc_common.c
int adc_sequence_validate_buffer(const struct adc_sequence *sequence,
				 uint8_t active_channels, size_t data_size)
{
	size_t needed = (size_t)active_channels * data_size;

	if (sequence->options) {
		needed *= (1 + sequence->options->extra_samplings);
	}

	if (sequence->buffer_size < needed) {
		return -ENOMEM;
	}

	return 0;
}

Source: Zephyr commit 9338c518

Detection Methods for CVE-2026-18413

Indicators of Compromise

  • Unexpected kernel panics, memory faults, or thread stack corruption on devices running Zephyr with the NXP MCUX LPADC driver
  • Application threads issuing adc_read() calls with buffer_size smaller than active_channels * sizeof(uint16_t) * (1 + extra_samplings)
  • Anomalous ADC sequences from user-mode threads specifying unusually large options->extra_samplings values

Detection Strategies

  • Perform static analysis of firmware to identify calls into the LPADC driver where buffer size arithmetic is not validated by the caller
  • Audit device tree and Zephyr application manifests for LPADC device objects granted to user-mode threads via memory domains
  • Review commits against the fixed baseline referenced in GHSA-7jqq-2g5q-hcrp to confirm the driver imports adc_common.h

Monitoring Recommendations

  • Enable Zephyr fault handlers and stack sentinel features to surface kernel memory corruption early in test cycles
  • Log ADC driver return codes during integration testing to detect -ENOMEM responses that indicate undersized buffers
  • Instrument fuzz testing of the ADC syscall surface on CONFIG_USERSPACE builds to exercise boundary conditions in buffer_size and extra_samplings

How to Mitigate CVE-2026-18413

Immediate Actions Required

  • Update Zephyr RTOS to a release containing commits 3bda971a and 9338c518, which introduce and adopt adc_sequence_validate_buffer()
  • Rebuild and reflash all devices using the NXP MCUX LPADC or ADI MAX32 ADC drivers
  • Audit user-mode threads that are granted access to LPADC device objects and restrict their memory domains where feasible

Patch Information

The upstream fix adds a shared helper adc_sequence_validate_buffer() in drivers/adc/adc_common.c and calls it from mcux_lpadc_start_read() before any sampling starts. The helper computes active_channels * sizeof(uint16_t) * (1 + extra_samplings) and returns -ENOMEM when the buffer is undersized. See the Zephyr driver patch and the common helper commit for the complete change set.

Workarounds

  • Disable CONFIG_USERSPACE on builds that do not require user-mode isolation to eliminate the privilege escalation vector
  • Revoke user-mode access to LPADC device objects until the patched Zephyr version is deployed
  • Wrap application-side adc_read() calls with explicit buffer-size validation matching the helper formula
bash
# Verify Zephyr tree contains the fix
git -C zephyr log --oneline drivers/adc/adc_common.c \
  | grep -E "9338c518|3bda971a"
grep -n "adc_sequence_validate_buffer" \
  zephyr/drivers/adc/adc_mcux_lpadc.c

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.