CVE-2026-93119
NoneCVSS
—
EPSS
0.2%
Published
Sep 17, 2026
CISA due date
—
Cloudanix analysis
A flaw in the Linux kernel's handling of certain USB devices can let a malicious gadget corrupt internal memory and potentially take control of the computer or crash it.
- Exploitation
- Physical Access
- Attacker needs
- Physical Access
- Complexity
- Moderate
- Impact
- Privilege Gain
- Component
- OS kernel
- Class
- Buffer Overflow
- Remediation
- Patch
- Effort
- Medium
- Patch risk
- Low
What it actually does
Out-of-bounds write on the kernel stack in ljca_enumerate_gpio() when a device reports a bank_num value that passes length and pin-count checks but exceeds the two-entry valid_pin[] array, allowing up to nine u32 writes beyond the buffer.
Why it matters to the business
Systems using LJCA-based USB GPIO devices face risk of kernel memory corruption that can cause crashes, data loss, or local privilege escalation; the issue affects any kernel build containing the vulnerable driver regardless of specific hardware deployment volume.
How an attack unfolds
An attacker supplies a malicious or intentionally broken LJCA USB device that responds to enumeration with a bank_num of 9 and pins_per_bank of 7. The two pre-loop sanity checks pass because the reply size stays under 60 bytes and total pins stay under the maximum, yet the subsequent loop writes nine values into a two-slot stack array, corrupting adjacent kernel stack frames and enabling control-flow hijacking or denial of service.
How to fix it
Apply the upstream kernel patch that adds an explicit bounds check rejecting any bank_num larger than the capacity of valid_pin[] before entering the loop; rebuild and reboot with the fixed kernel. Where live patching is available, apply the vendor hotfix for the ljca module.
How to confirm the fix worked
Confirm the patched kernel source contains the added bank_num <= ARRAY_SIZE(valid_pin) check in ljca_enumerate_gpio(); on a test system, attach a device emulator that returns bank_num=9 and verify the driver now rejects the descriptor instead of writing past the array.
Typical attack path
- Attacker connects a crafted LJCA USB device to the target system
- Kernel USB subsystem loads the ljca driver and calls ljca_enumerate_gpio()
- Device returns a descriptor with bank_num=9 that satisfies struct_size and pin-count checks
- Loop writes beyond valid_pin[] on the stack, corrupting kernel memory
- Attacker leverages the resulting corruption for privilege escalation or crash
How to detect it
Search kernel logs (dmesg, journalctl) and crash dumps for stack traces containing ljca_enumerate_gpio or references to valid_pin array overruns; inspect USB device descriptors from newly attached devices for unusually high bank_num values near the LJCA payload limit.
What your security team should do
- Prioritize kernel updates on any host that may connect untrusted USB devices
- Add the ljca module to the list of drivers disabled via modprobe.blacklist on systems that do not require LJCA GPIO functionality
- Monitor kernel logs for oops or stack trace mentions of ljca_enumerate_gpio after any USB device attachment
The record
In the Linux kernel, the following vulnerability has been resolved: usb: ljca: bound bank_num in ljca_enumerate_gpio() ljca_enumerate_gpio() reads desc->bank_num from the device and loops valid_pin[i] = get_unaligned_le32(...) for i < bank_num. valid_pin[] holds only LJCA_MAX_GPIO_NUM / 32 = 2 entries. Two checks run before the loop. The reply length must match struct_size(desc, bank_desc, bank_num). The product pins_per_bank * bank_num must not exceed LJCA_MAX_GPIO_NUM. Neither one bounds bank_num against the size of valid_pin[]. The reply is capped at LJCA_MAX_PAYLOAD_SIZE (60) bytes, so the struct_size check limits bank_num to 9. A device that reports bank_num 9 with pins_per_bank 7 still passes both checks. gpio_num is 63 and the reply is 56 bytes. The loop then writes nine u32 into the two entry array and overruns valid_pin[] on the stack. A broken or malicious LJCA device can therefore overflow the stack. Reject a bank_num that does not fit valid_pin[].
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|