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

CVE-2026-19676: PECI Driver Privilege Escalation Vulnerability

CVE-2026-19676 is a privilege escalation flaw in PECI drivers that enables user-mode threads to escape to kernel privileges through unchecked buffer pointers, allowing arbitrary kernel memory access and code execution.

Published:

CVE-2026-19676 Overview

CVE-2026-19676 is a kernel memory corruption vulnerability in the Zephyr RTOS Platform Environment Control Interface (PECI) subsystem. The user-mode verifier z_vrfy_peci_transfer() in drivers/peci/peci_handlers.c validates only the outer struct peci_msg and leaves the embedded tx_buffer and rx_buffer pointers caller-controlled. In-tree PECI drivers dereference those pointers in supervisor mode, giving a user-mode thread an arbitrary kernel read and write primitive. The flaw is classified under [CWE-822: Untrusted Pointer Dereference].

Critical Impact

A user-mode application granted the PECI device object can read or write arbitrary kernel memory, escalating to supervisor-mode code execution.

Affected Products

  • Zephyr RTOS builds with CONFIG_USERSPACE=y and CONFIG_PECI_NPCX enabled
  • Zephyr RTOS builds with CONFIG_USERSPACE=y and CONFIG_PECI_XEC enabled
  • Zephyr RTOS builds with CONFIG_USERSPACE=y and CONFIG_PECI_ITE_IT8XXX2 enabled

Discovery Timeline

  • 2026-10-21 - CVE-2026-19676 published to NVD
  • 2026-10-22 - Last updated in NVD database

Technical Details for CVE-2026-19676

Vulnerability Analysis

The PECI subsystem exposes peci_transfer() as a system call that user-mode threads can invoke after being granted the PECI device object. The verifier calls k_usermode_from_copy() to duplicate the struct peci_msg argument into kernel memory. This copy only duplicates the outer structure. The embedded struct peci_buf members tx_buffer and rx_buffer still carry caller-supplied buf pointers and len values.

Every in-tree PECI driver dereferences those pointers directly in supervisor mode. peci_npcx_transfer() in drivers/peci/peci_npcx.c and peci_it8xxx2_transfer() in drivers/peci/peci_ite_it8xxx2.c copy hardware bytes into rx_buffer.buf[i] and read command bytes out of tx_buffer.buf[i]. peci_xec_read() and peci_xec_write() in drivers/peci/peci_mchp_xec.c perform equivalent accesses with no bound checking on rx_buffer.len.

Root Cause

The verifier failed to apply K_SYSCALL_MEMORY_READ() and K_SYSCALL_MEMORY_WRITE() checks against the embedded buffer pointers. These macros confirm that a user-mode address range is readable or writable from the calling thread. Without them, kernel addresses pass validation unchanged.

Attack Vector

An attacker needs local code execution in a user-mode thread holding the PECI device under CONFIG_USERSPACE. By pointing rx_buffer.buf at kernel structures, the attacker causes the driver to write hardware-supplied bytes into kernel memory. By pointing tx_buffer.buf at kernel memory, the attacker leaks kernel contents onto the PECI or eSPI out-of-band bus where a bus observer can capture them. Supplying an unmapped address triggers a supervisor-mode fault.

c
 	K_OOPS(K_SYSCALL_DRIVER_PECI(dev, transfer));
 	K_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(*msg)));
 
+	/**
+	 * k_usermode_from_copy() only duplicates the outer struct; the buffer
+	 * pointers it carries are still caller supplied and the driver
+	 * dereferences them in supervisor mode, so they must be checked here.
+	 */
+	if ((msg_copy.tx_buffer.buf != NULL) && (msg_copy.tx_buffer.len > 1U)) {
+		K_OOPS(K_SYSCALL_MEMORY_READ(msg_copy.tx_buffer.buf,
+					     msg_copy.tx_buffer.len - 1U));
+	}
+
+	if (msg_copy.rx_buffer.buf != NULL) {
+		size_t rx_len;
+
+		K_OOPS(K_SYSCALL_VERIFY_MSG(!size_add_overflow(msg_copy.rx_buffer.len,
+							       1U, &rx_len),
+					    "rx_buffer.len overflow"));
+		K_OOPS(K_SYSCALL_MEMORY_WRITE(msg_copy.rx_buffer.buf, rx_len));
+	}
+
 	return z_impl_peci_transfer(dev, &msg_copy);
 }

Source: Zephyr Project patch commit d7faf32. The patch adds K_SYSCALL_MEMORY_READ() and K_SYSCALL_MEMORY_WRITE() checks on the embedded buffers and guards the RX length addition with size_add_overflow() to account for the frame-check-sequence byte.

Detection Methods for CVE-2026-19676

Indicators of Compromise

  • Unexpected supervisor-mode faults originating from peci_npcx_transfer(), peci_it8xxx2_transfer(), peci_xec_read(), or peci_xec_write()
  • PECI bus traffic containing byte sequences that match kernel symbol or stack content
  • Repeated peci_transfer() system calls from a single user-mode thread with varying buffer addresses

Detection Strategies

  • Audit Zephyr build configurations for the combination of CONFIG_USERSPACE=y with any of CONFIG_PECI_NPCX, CONFIG_PECI_XEC, or CONFIG_PECI_ITE_IT8XXX2
  • Review user-mode thread code that holds the PECI device object for buffer pointers originating outside the thread's partition
  • Add instrumentation in test builds that logs the resolved address range of tx_buffer.buf and rx_buffer.buf on each call

Monitoring Recommendations

  • Capture PECI and eSPI bus traces during security testing to detect kernel-content disclosure
  • Alert on crash dumps where the fault PC lies inside a PECI driver transfer routine
  • Track firmware versions deployed to baseboard management controllers and server platforms that integrate Zephyr with PECI

How to Mitigate CVE-2026-19676

Immediate Actions Required

  • Apply the upstream Zephyr fix in commit d7faf323d52b7e8845a63b1f854a82bdda44c261 and rebuild affected firmware images
  • Revoke the PECI device object from user-mode threads that do not require direct hardware access
  • Audit downstream forks of Zephyr for backports of the PECI subsystem to confirm the patched verifier is present

Patch Information

The fix is tracked in GitHub Security Advisory GHSA-g66q-frxm-3hfg and merged in Zephyr Project commit d7faf32. The patch adds explicit K_SYSCALL_MEMORY_READ() and K_SYSCALL_MEMORY_WRITE() checks on the embedded tx_buffer and rx_buffer members and guards RX length arithmetic with size_add_overflow().

Workarounds

  • Disable the vulnerable PECI drivers by unsetting CONFIG_PECI_NPCX, CONFIG_PECI_XEC, and CONFIG_PECI_ITE_IT8XXX2 where PECI access is not required
  • Disable CONFIG_USERSPACE on firmware builds where separation between user-mode and supervisor-mode threads is not needed
  • Wrap PECI access behind a trusted supervisor-mode service that validates buffer ownership before invoking the driver
bash
# Remove vulnerable PECI drivers from the Zephyr build configuration
# in prj.conf when PECI functionality is not required
CONFIG_PECI=n
CONFIG_PECI_NPCX=n
CONFIG_PECI_XEC=n
CONFIG_PECI_ITE_IT8XXX2=n

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.