Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessGain local unprivileged code execution
-
DeliveryBrute-force ¤t linear-map address under KASLR
-
ExploitSet tp to forged task_struct and trap
-
ExecutionKernel skips shadow call stack reload
-
PersistReturn through attacker-controlled gp (poisoned ra)
-
ImpactKernel arbitrary write and control-flow hijack
Vulnerability Assessment
| Exploitation Conditions | Exploitation requires a Linux kernel built for the RISC-V architecture with CONFIG_SHADOW_CALL_STACK enabled - on that configuration gp is the shadow call stack pointer and load_global_pointer is a no-op, which is what makes the poisoned pointer dangerous. The attacker must already have local unprivileged code execution (CVSS PR:L) to run a task that writes the user-controllable tp register and then traps into the kernel. A practical limiting factor is that the attacker must learn the linear-map address of its own task_struct (¤t); with KASLR enabled this requires brute forcing, which the researchers reported achieving in testing. Kernels not built with CONFIG_SHADOW_CALL_STACK, or non-RISC-V kernels, are not affected. Once gp is poisoned it is saved to task_struct.scs_sp, so the faulty reload is skipped on every subsequent entry, making the primitive persistent for that task. |
| Impact | The impact signals are severe: the description establishes an unprivileged, local attacker-to-kernel arbitrary-write and control-flow-hijack primitive, which the CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H vector (7.8) reflects with full C/I/A impact. However, exposure is sharply constrained by preconditions: the flaw only exists on RISC-V kernels built with CONFIG_SHADOW_CALL_STACK, so the vulnerable population is a small subset of all Linux deployments. This explains the low EPSS of 0.21% (11th percentile) and the absence of any KEV listing or public exploit - the SSVC-style priority label is 'this_week', consistent with a serious but non-emergency local-escalation bug rather than a mass-exploited remote one. A notable conflict: the input Tags label this 'Information Disclosure', but the description and the C:H/I:H/A:H vector describe a write/control-flow-hijack (privilege-escalation) primitive, not merely disclosure - the tag understates and mischaracterizes the impact. Net: a genuine high-severity local kernel privilege-escalation issue that warrants prompt patching on affected RISC-V/SCS systems, but not a broad internet-facing emergency given the local vector (AV:L) and narrow affected configuration. |
| Exploit ScenarioDerived | An unprivileged local user on a RISC-V Linux system built with CONFIG_SHADOW_CALL_STACK sets the user-writable tp register to the linear-map address of its own task_struct (¤t), brute-forced under KASLR, then triggers a trap. handle_exception() wrongly concludes the trap came from the kernel, skips reloading the shadow call stack pointer (gp), and continues using the attacker-controlled gp; subsequent non-leaf-function 'sd ra'/'ld ra' operations then write to and return through an attacker-chosen address, yielding kernel arbitrary write and control-flow hijack. No public exploit is identified at time of analysis, though the report notes the KASLR brute-force was demonstrated by the researchers in testing. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 24, 2026
Local privilege escalation and kernel control-flow hijack affect RISC-V Linux kernels built with CONFIG_SHADOW_CALL_STACK. An attacker with local unprivileged code execution can set the user-writable tp register to the linear-map address of its task_struct so exception entry incorrectly skips reloading the shadow call stack pointer (gp); the poisoned gp is then used for shadow-stack stores and return-address loads, producing an arbitrary-write and control-flow-hijack primitive that persists for that task. The flaw is not in CISA KEV and no public exploit identified at time of analysis; EPSS is 0.21%.
RemediationAI
Vendor-released patch: Linux 7.3, 6.18.57, 7.2.11, and 6.12.113, corresponding to upstream commits 7d1367a53137e379498eb8791295e58854378636, 4d0697f192975dab5985e921989be1d85cf580e9, 37b4401ee6fa06046446d55e97e8d11784080843, and 6639735367a7d491977e9e5e7afc50b489d81d83. Apply the appropriate stable update or cherry-pick the relevant commit; no workaround is described in the supplied sources. If patching must be delayed, rebuilding the RISC-V kernel without CONFIG_SHADOW_CALL_STACK removes the vulnerable shadow-stack pointer handling for this flaw, at the cost of losing shadow call stack hardening, and reducing local unprivileged code execution limits exposure. Advisory: https://nvd.nist.gov/vuln/detail/CVE-2026-99018.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
RISC-V exception entry in handle_exception() decides whether to reload the kernel shadow call stack by comparing the trap-time tp value against current tp. Because tp is user-writable, a task can point it at ¤t to make the comparison succeed, causing scs_load_current to be skipped. Under CONFIG_SHADOW_CALL_STACK, gp is the shadow call stack pointer and load_global_pointer is a no-op, so compiler-emitted "sd ra, -8(gp)" and "ld ra, -8(gp)" operations write through and return through an attacker-controlled address. The fix uses the hardware sstatus.SPP bit, already available in s1 at that point, to distinguish user entries (SPP=0, reload) from nested kernel entries (SPP=1, skip), since SPP is set by hardware on trap entry and cannot be forged from U-mode. Exploitation requires local unprivileged execution on affected RISC-V builds and knowledge of the task_struct linear-map address, which KASLR makes probabilistic or brute-forceable as described in the supplied testing. No CWE was assigned.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Local unprivileged account can forge tp and trigger a trap (AV:L/PR:L/UI:N); reliable per vendor testing (AC:L); kernel arbitrary write and control-flow hijack gives full C:H/I:H/A:H.
Primary rating from Vendor (Linux).
CVSS VectorVendor: Linux
Lifecycle Timeline
4DescriptionCVE.org
In the Linux kernel, the following vulnerability has been resolved:
riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
Under CONFIG_SHADOW_CALL_STACK, handle_exception() reloads the kernel shadow call stack pointer (gp) only when the trap came from userspace. It made that decision with scs_load_current_if_task_changed, which compares the trap-time tp (read back from sscratch into s5) against the current tp:
beq \prev, tp, _skip_scs scs_load_current _skip_scs:
tp is a user-writable register. A user task that sets tp to the linear-map address of its own task_struct (¤t) before trapping makes the comparison succeed (can achieve by brute force with KASLR enable under our test), so the kernel skips scs_load_current and keeps running with the gp that userspace left in place. Under CONFIG_SHADOW_CALL_STACK gp is the shadow call stack pointer and load_global_pointer is a no-op, so the compiler-emitted "sd ra, -8(gp)" / "ld ra, -8(gp)" in every non-leaf function then write to, and return through, an attacker-controlled address -- an unprivileged kernel arbitrary-write and control-flow-hijack primitive. The poisoned gp is saved to task_struct.scs_sp on return, so the reload is skipped on every subsequent entry as well.
Decide "came from userspace" from the hardware sstatus.SPP bit (already in s1 at this point) instead of from tp, mirroring the check that ret_from_exception already uses a few instructions later. SPP is written by hardware on trap entry and cannot be forged from U-mode. Legitimate behaviour is unchanged: user entries (SPP=0) reload the task shadow call stack, nested kernel entries (SPP=1) skip it.
Executive ViewAI
CVE-2026-99018 is a high-severity local privilege escalation vulnerability in the Linux kernel for RISC-V architectures, specifically those built with the CONFIG_SHADOW_CALL_STACK security feature. It allows an attacker with local unprivileged access to corrupt kernel memory and hijack control flow, potentially leading to full system compromise on affected RISC-V devices. Leadership should prioritize remediation for any RISC-V Linux systems handling sensitive data or supporting multi-user workloads, as exploitation could result in unauthorized access and data integrity loss.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
EUVD-2026-108812
GHSA-7x79-hrpm-vw9w
NVD
CVE.org
EPSS
Exploit-DB