Cloudanix VulnDB

CVE-2026-89596

High · 7.1

CVSS

7.1

EPSS

0.2%

Published

Sep 11, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

An older NVIDIA network driver in Linux can make a computer crash or fail to wake when it goes to sleep, because it accidentally touches memory just past the area it is allowed to use.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Moderate
Impact
Denial Of Service
Component
OS kernel
Class
Buffer Overflow
Remediation
Upgrade
Effort
Medium
Patch risk
None

What it actually does

An off-by-one in the Linux kernel forcedeth (NVIDIA nForce Ethernet) driver causes nv_suspend() and nv_resume() to iterate one u32 past saved_config_space and past the ioremap'd MMIO window (base + register_size). That produces an out-of-bounds array access (adjacent to name_rx), a stray MMIO read on suspend, and a stray MMIO writel() on resume. With CONFIG_UBSAN_TRAP the access becomes a kernel trap that aborts the running path; otherwise it is a local integrity and availability defect in the power-management path. Confidentiality is not affected. VER3 devices index one past a 385-element u32 array; VER1/VER2 stay inside the array but still touch one dword past their mapped BAR window.

Why it matters to the business

Systems using the in-tree forcedeth NIC can fail, hang, or panic during sleep/wake (S3) instead of completing suspend/resume, causing downtime, lost in-flight work, and unstable networking after resume. Impact is concentrated on older NVIDIA MCP Ethernet hardware (for example MCP79-class machines), not modern NVIDIA GPUs or most cloud fleets. Exploitation maturity is none, EPSS remains ~0.0018 and flat over 30 days, the CVE is not in CISA KEV, and it is not associated with ransomware, so organizational urgency is patch-in-cycle rather than emergency unless hosts frequently suspend or run UBSAN_TRAP kernels. Published about five weeks ago with no named threat-actor use.

How an attack unfolds

A local, low-privileged user on a machine whose Ethernet is bound to forcedeth needs the suspend/resume code to run. They either wait for a normal sleep cycle or induce power management (for example writing a sleep state if policy allows). pci_pm_suspend calls nv_suspend, which walks non-PCI config with a <= bound and reads one dword past the mapped registers into/beyond saved_config_space; pci_pm_resume's matching loop writes that extra dword to base+0x604 (or one dword past smaller VER1/VER2 windows). Adjacent name_rx is notionally in the overflow slot but is rewritten before request_irq, so practical attacker-controlled corruption is limited; the reliable outcomes are UBSAN reports, a kernel trap when UBSAN_TRAP is on, or undefined MMIO side effects that can panic or corrupt device state. There is no remote entry, no known in-the-wild exploit, and no public exploit maturity.

How to fix it

Apply the upstream forcedeth fix that changes both save/restore loops from <= to < so exactly register_size bytes are copied, then deploy a kernel (or distro package) that includes that change. If a patched kernel is not yet available, avoid deep S3/suspend-to-RAM on forcedeth hosts, or unload/blacklist forcedeth only when that NIC is unused and an alternate interface exists. Do not rely on rewriting name_rx as a fix; the defect is the OOB access and unmapped MMIO. Track vendor kernel advisories for the exact stable-tree commit and package versions as they are published; no per-product fixed versions were supplied with this record.

How to confirm the fix worked

After patching, confirm the running kernel contains the forcedeth change (loop condition is i < np->register_size/sizeof(u32) in both nv_suspend and nv_resume) via package changelog, git log, or disassembly of the module. On a non-production host with the same NVIDIA MCP NIC, perform repeated S3 cycles with CONFIG_UBSAN and dmesg/journal collection; a fixed kernel must not report array-index-out-of-bounds at forcedeth.c suspend/resume lines and must not trap. Inventory exposure with lsmod, sysfs driver links, and PCI IDs bound to forcedeth. Unpatched UBSAN kernels typically report the issue only on the first suspend/resume after module load (source_location suppression), so a single clean cycle is not proof on older builds.

Typical attack path

  1. Obtain local (non-remote) access on a Linux host whose NIC is driven by forcedeth (NVIDIA MCP/nForce Ethernet).
  2. Confirm the forcedeth module is loaded and the device is a VER1/VER2/VER3 part that programs register_size and ioremaps only that window.
  3. Trigger or wait for a PCI power-management suspend (deep S3 or equivalent), so nv_suspend runs the off-by-one save loop.
  4. Allow resume so nv_resume performs the matching extra MMIO writel past the mapped BAR.
  5. Rely on the out-of-bounds access, UBSAN_TRAP abort, or stray MMIO to crash the kernel or disrupt the NIC rather than achieve reliable code execution.

How to detect it

This is a local power-management bug, not a network worm; look for evidence of the OOB access during suspend/resume rather than C2. Search kernel logs (dmesg, journald, serial/console, crash dumps, pstore) for UBSAN array-index-out-of-bounds in drivers/net/ethernet/nvidia/forcedeth.c, especially around the historical suspend/resume line numbers, with a call chain through pci_pm_suspend, pci_pm_resume, dpm_run_callback, and device_suspend. Index 385 vs type u32 [385] is the VER3 signature. UBSAN reports each source location only once per module load, so later S3 cycles may be silent even if the access still happens—correlate with forcedeth loaded and S3 around the same time. Panic/oops with forcedeth on the stack during PM transitions, unexplained NIC loss after resume, or MMIO faults just past the BAR mapping are additional artifacts. No named APT campaigns or ransomware use are associated, so do not expect unique malware hashes.

  • UBSAN: array-index-out-of-bounds in drivers/net/ethernet/nvidia/forcedeth.c
  • index 385 is out of range for type 'u32 [385]'
  • drivers/net/ethernet/nvidia/forcedeth.c:6225
  • drivers/net/ethernet/nvidia/forcedeth.c:6240
  • __ubsan_handle_out_of_bounds
  • forcedeth
  • pci_pm_suspend
  • pci_pm_resume
  • nv_suspend
  • nv_resume

What your security team should do

  • Inventory Linux hosts whose Ethernet is bound to forcedeth and prioritize those that use S3/suspend or UBSAN_TRAP kernels.
  • Schedule kernel updates that include the forcedeth off-by-one fix; this is not a KEV/emergency item given EPSS ~0.0018, no known exploits, and local-only attack.
  • Until patched, reduce suspend/resume on affected NICs and alert on forcedeth UBSAN or panic traces during pci_pm_suspend/pci_pm_resume.
  • Do not treat this as ransomware or APT-driven; keep it in the normal kernel patch cadence unless you have many legacy NVIDIA MCP endpoints.
  • Verify the related 2012 nv_get_regs() overflow fix is also present so all three register-walk sites are consistent.

The record

In the Linux kernel, the following vulnerability has been resolved: forcedeth: fix off-by-one when saving/restoring non-PCI config space nv_suspend() and nv_resume() walk the non-PCI configuration space with for (i = 0; i <= np->register_size/sizeof(u32); i++) which runs one iteration too many. saved_config_space is declared as u32 saved_config_space[NV_PCI_REGSZ_MAX/4]; and NV_PCI_REGSZ_VER3 is equal to NV_PCI_REGSZ_MAX (0x604), so on a VER3 device register_size/sizeof(u32) is exactly the array length and the last iteration addresses one element past the end. The element it lands on is np->name_rx[0..3]: saved_config_space[] is followed immediately by char name_rx[IFNAMSIZ + 3], and char needs no padding. Nothing observable is corrupted by that, because nv_request_irq() rewrites name_rx with sprintf() before it is ever passed to request_irq(). The bug is the out-of-bounds access itself, which UBSAN reports and which CONFIG_UBSAN_TRAP=y turns into a trap that aborts the running kernel code, plus an MMIO read and, on resume, an MMIO writel() to base + 0x604, one dword past the range the driver mapped: np->base = ioremap(addr, np->register_size); VER1 and VER2 devices stay inside the array, but they too get the stray read and the stray write one dword past their own window. Caught by UBSAN on an Apple Macmini3,1 (MCP79) during a deep S3 cycle. The splat below is trimmed: the build path in the file name, the CPU and taint lines, the Workqueue line, the "?" hint frames, and the frames below device_suspend are all cut. The kernel was tainted, with an out-of-tree nouveau and CPU_OUT_OF_SPEC; forcedeth itself was the stock module. UBSAN: array-index-out-of-bounds in drivers/net/ethernet/nvidia/forcedeth.c:6225:25 index 385 is out of range for type 'u32 [385]' Call Trace: dump_stack_lvl+0x5d/0x80 ubsan_epilogue+0x5/0x2b __ubsan_handle_out_of_bounds.cold+0x54/0x59 __this_module+0xe398c/0xe9010 [forcedeth] pci_pm_suspend+0x80/0x170 dpm_run_callback+0x51/0x160 device_suspend+0x1a2/0x4a0 ... Both loops are hit. UBSAN reports each source location only once per module load (__ubsan_handle_out_of_bounds() calls suppress_report(), which does test_and_set_bit(REPORTED_BIT, ...) on the struct source_location), so the two splats land in the first S3 cycle after the module is loaded and later cycles are silent even though the access still runs off the end every time. In that first cycle line 6225 is reported from pci_pm_suspend and line 6240 from pci_pm_resume. The same off-by-one was fixed in nv_get_regs() by commit ba9aa134287f ("forcedeth: fix buffer overflow") in 2012; these two loops were missed. The suspend and resume side was reported on LKML in September 2013 by Marc Weber, with the same analysis and the same one-character fix, but the patch was attached rather than sent inline and the thread ended there. Use < instead of <=, which saves and restores exactly register_size bytes.

Affected packages

Ecosystem Package Introduced Fixed