Skip to content

Cortex-A7 module data validation checks only the first address of a caller-supplied range

High
fdesbiens published GHSA-fvp6-37q5-c648 Oct 2, 2026

Package

ThreadX (Eclipse ThreadX)

Affected versions

>= 6.1, <= 6.5.1.202602a

Patched versions

6.5.2.202603

Description

Summary

The Cortex-A7 MMU Modules port validates a caller-supplied buffer by translating one address — the first byte. The common Module Manager hands its range check the module instance, the start address and the complete byte size; the Cortex-A7 implementation discarded the instance and the size and asked the MMU a single question about the start.

A memory-protected module therefore passed any range whose first byte was user-readable, however far the rest of it reached. Privileged dispatch code then read or wrote the whole range. Because every protected-module dispatcher that consumes a buffer or an extra-parameter array goes through this one macro, the defect is not in any individual service: it is in the primitive all of them rely on.

Details

TXM_MODULE_MANAGER_CHECK_INSIDE_DATA is the port's answer to "may this module touch these bytes?". The Cortex-A7 version called _txm_module_manager_inside_data_check((ULONG)obj_ptr), which performs a single ATS1CUR translation.

That operation tests an unprivileged read at one address. It establishes nothing about the last byte, the 4 KiB pages in between, integer wraparound of obj_ptr + obj_size, ownership of the memory by the requesting module, or unprivileged write permission. The read intent is the wrong question for TXM_MODULE_MANAGER_PARAM_CHECK_BUFFER_WRITE, whose contract requires writable data or shared memory rather than merely readable code or data.

Queue receive shows the write-oriented path. A protected module obtains a queue with a multi-word message size and passes a destination whose first byte sits in a readable mapped page but whose full range crosses the page or region end. The dispatcher computes the byte count and calls PARAM_CHECK_BUFFER_WRITE, the Cortex-A7 implementation translates the start address alone and returns true, and _txe_queue_receive then copies the complete message in privileged context — including the bytes past the end of what was checked.

Read-oriented dispatchers have the inverse problem: privileged code reads beyond the module-owned source and returns or enqueues those bytes. Where the neighbouring page is unmapped, the same condition yields a privileged data abort instead.

The reachable surface is wide. Queue send and receive, the information getters, event and pool services, object lookup, and the extra-parameter arrays all pass through the affected macros before privileged code dereferences a module-controlled range.

Impact

A module whose only privilege is the right to make ordinary system calls can drive privileged code into out-of-bounds reads and writes. Depending on the service and the virtual layout, that means disclosure of adjacent privileged data, modification of memory outside the module's writable mapping, modification of read-only module code through a write-output API, or a kernel-mode fault.

The exposure is only as large as what sits next to a module mapping. Where the layout places an unmapped guard after every module region, the reachable consequence is the privileged fault rather than disclosure or corruption.

No race, ISR context, disabled error checking or object corruption is required.

Affected configurations

Cortex-A7 MMU Modules builds — GNU, AC5 or IAR — with TXM_MODULE_MEMORY_PROTECTION. Every other module port carries its own range-complete implementation of the same macro and is unaffected.

The port and the single-address check arrived together in commit 1b5816a2, the 6.1 minor release. Every release from v6.1_rel through v6.5.1.202602a_rel carries it, including both 6.5.1 releases. The 6.0.x releases predate the Cortex-A7 module port entirely.

Severity

CVSS v4.0 base score 8.5 (High) CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

The actor is module code already running on the device, needing syscall access but not privileged CPU access, and no user interaction. A pointer placed near a mapped boundary and an ordinary kernel request are sufficient. The vulnerable condition is the supported memory-protected Modules configuration itself, not an exceptional runtime state. Exploit Maturity was not assessed, so EQ5 takes the v4.0 default of E:A.

Subsequent-system metrics are N: only the ThreadX instance is claimed, and product-level physical effects are deployment-specific.

The all-high vulnerable-system impact assumes a deployment in which a module mapping is adjacent to privileged memory or to another module's. An integrator whose page-table layout guarantees an unmapped guard after every module region should reduce confidentiality and integrity in their Environmental metrics; the availability impact remains either way.

Patches

Fixed in ThreadX 6.5.2.202603.

The check now takes the range size and an access intent. The module's own data region is answered from the Module Manager's records, which name it exactly and cost no address translations; everything else is answered by translating every page the range touches with the requested unprivileged access. Empty ranges, ranges whose last byte would wrap, and ranges that leave the recorded data region partway through are refused. The page walk is bounded by TXM_MODULE_MANAGER_DATA_CHECK_MAX_PAGES, so one module request cannot impose unbounded work on the kernel, and translation results are trusted only while the requesting module's own address-space context is loaded.

The outside direction has its own check rather than being the negation of the inside one. Negating a range-complete inside check would report a range reaching into the module only partway as being outside it, which _txm_module_manager_param_check_object_for_use would then accept as a kernel object.

Other ports are untouched. The backward-compatible fallbacks in txm_module_manager_util.h keep their single data check, and the preprocessed dispatch output for all 23 other module ports that GCC can preprocess is byte-identical to the unfixed tree.

Verification: host suite 99/99 across all five build configurations under GCC 13.3.0 and GCC 14.2.0; the Cortex-A7 module manager cross-compiles clean under GCC 14.3.1 at -Wall -Wextra -Werror against the port's own shipped headers; the bounded host regression test passes on an emulated Cortex-A7 at every optimisation level and fails 24 expectations against a shim reproducing the pre-fix behaviour; 100% line, branch and call coverage of the new logic.

The CP15 address translation is exercised rather than stubbed. A second test builds a short-descriptor translation table, enables the MMU, and drives the real check through the real translation operations on a real Cortex-A7 translation regime. It confirms what a simulated page map could only assume: ATS1CUW denies a write to an unprivileged read-only mapping while ATS1CUR allows the read, so the write intent does what the fix depends on; a range leaving its mapping partway through is rejected, while translating only its first address accepts it; and privileged-only memory is reachable by neither intent and is reported outside the module. Reverting the page walk to a single page makes exactly the boundary case fail, so the test is known to detect the regression it guards.

Still unverified: these checks run under an emulator, which implements the architecture rather than a particular silicon implementation, so errata, cache and TLB interactions and speculative effects remain outside their reach. The AC5 and IAR builds of the port also still need their native toolchains.

Workarounds

None that preserve the feature. Every path here is reachable only from a module the Module Manager has loaded, so a system that loads only modules it builds itself is not exposed — but that is precisely the assumption module memory protection exists so that you do not have to make.

Credits

Found and fixed by Frédéric Desbiens (@fdesbiens). The analysis, fix and regression tests were produced with AI assistance under human review, in accordance with the Eclipse Foundation's Generative AI Usage Guidelines.

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Local
Attack Complexity Low
Attack Requirements None
Privileges Required Low
User interaction None
Vulnerable System Impact Metrics
Confidentiality High
Integrity High
Availability High
Subsequent System Impact Metrics
Confidentiality None
Integrity None
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

CVE ID

CVE-2026-95109

Weaknesses

Out-of-bounds Read

The product reads data past the end, or before the beginning, of the intended buffer. Learn more on MITRE.

Out-of-bounds Write

The product writes data past the end, or before the beginning, of the intended buffer. Learn more on MITRE.

Credits