CVE-2026-98149 in Linuxinfo

Summary

by MITRE • 09/25/2026

In the Linux kernel, the following vulnerability has been resolved:

bpf: Fix percpu map update indexing with sparse CPU IDs

Per-CPU array, hash, and cgroup storage map updates without BPF_F_CPU or BPF_F_ALL_CPUS use a value buffer whose per-CPU slots are packed in possible-CPU order. The buffer is sized as:

round_up(value_size, 8) * num_possible_cpus()

The update paths iterate over possible CPUs, but use the logical CPU ID to calculate the source offset:

value + size * cpu

This only works when possible CPU IDs are contiguous starting at zero.

For example, with a possible CPU mask of 0,2-3, the buffer contains three slots corresponding to CPUs 0, 2, and 3. CPU2 is therefore expected to use slot 1 and CPU3 slot 2. Instead, the current code uses slots 2 and 3 respectively, causing incorrect per-CPU values and an out-of-bounds read from the update buffer for CPU3.

The corresponding lookup paths already use a dense offset while iterating over possible CPUs. Do the same for the array, hash, and cgroup storage update paths, advancing the source offset once for each possible CPU. BPF_F_ALL_CPUS continues to use the same value for every CPU.

If you want to get best quality of vulnerability data, you may have to visit VulDB.

Analysis

by VulDB Data Team • 09/25/2026

The Linux kernel contains a critical implementation flaw within the Berkeley Packet Filter (BPF) subsystem that affects per-CPU map updates when sparse or non-contiguous CPU identifiers are present in the system configuration. This vulnerability arises from an incorrect calculation of memory offsets during data insertion into per-CPU array, hash, and cgroup storage maps. Specifically, when a BPF program attempts to update these maps without explicitly specifying the BPF_F_CPU flag for a specific target or using BPF_F_ALL_CPUS to broadcast to all processors, the kernel relies on an internal iteration over possible CPUs. The underlying data structure allocates memory based on the total number of possible CPU IDs in the system, rounded up to align with eight-byte boundaries and multiplied by the value size. This allocation strategy assumes a dense mapping where logical CPU identifiers correspond directly to their index position within the allocated buffer.

The technical root cause lies in the mismatch between how the buffer is sized and how offsets are calculated during updates. The kernel allocates slots based on possible CPUs, which includes all CPUs that could potentially be online, even if they are currently offline or disabled due to hardware topology constraints such as NUMA nodes with missing cores. However, the update logic incorrectly uses the raw logical CPU ID to compute the source offset by multiplying it directly by the value size. This approach is only valid when possible CPU IDs form a contiguous sequence starting from zero. In systems where certain CPUs are absent or disabled, resulting in sparse identifiers such as 0, 2, and 3, this linear calculation fails. For instance, if CPU ID 2 is targeted, the code calculates an offset corresponding to index two rather than index one, which is the correct position for the second available slot in a packed array of possible CPUs.

This miscalculation leads to severe operational consequences, primarily involving data corruption and potential out-of-bounds memory access. When updating maps on sparse CPU IDs, the kernel writes or reads from incorrect memory locations within the value buffer. In scenarios where the calculated offset exceeds the actual allocated size for valid per-CPU slots, an out-of-bounds read occurs. This can lead to information disclosure by leaking kernel memory contents into user-space BPF programs or causing undefined behavior that may crash the system depending on what data resides at those invalid addresses. The lookup paths were already correctly implemented using dense offsets relative to possible CPUs, creating a dangerous asymmetry where reads function properly but writes corrupt data or trigger security violations.

From a classification perspective, this vulnerability aligns with CWE-125 Out-of-bounds Read and CWE-787 Out-of-bounds Write, as the incorrect indexing allows access beyond intended memory boundaries. It also relates to CWE-697 Incorrect Comparison during Conformance Testing if viewed through the lens of logical CPU mapping versus physical allocation indices. In terms of MITRE ATT&CK techniques, this flaw could be leveraged in conjunction with privilege escalation or defense evasion strategies by an attacker who controls BPF program execution, potentially allowing them to read sensitive kernel data or destabilize the host environment for denial-of-service purposes. The vulnerability highlights the complexity of managing hardware topology variations within high-performance networking and observability frameworks like eBPF.

To mitigate this risk, the Linux kernel has been patched to correct the offset calculation logic in the update paths for array, hash, and cgroup storage maps. The fix ensures that the source offset advances once for each possible CPU encountered during iteration, effectively mapping logical operations to dense indices within the allocated buffer rather than using raw CPU IDs. This change maintains compatibility with existing BPF programs while ensuring correct behavior on systems with sparse or non-contiguous CPU configurations. System administrators and developers should ensure their kernels are updated to include this fix, particularly in environments utilizing virtualization technologies or hardware platforms that expose partial core sets to the guest operating system. Regular patching of the kernel is essential to prevent exploitation of these low-level memory management errors which can have significant security implications for containerized workloads relying on BPF for network filtering and performance monitoring.

Responsible

Linux

Reservation

09/25/2026

Disclosure

09/25/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

very low

Sources

Do you want to use VulDB in your project?

Use the official API to access entries easily!