Bug 2478652 (CVE-2026-114690) - CVE-2026-114690 gcc: Confirmed out-of-bounds read/write in libstdc++ parallel `std
Summary: CVE-2026-114690 gcc: Confirmed out-of-bounds read/write in libstdc++ parallel...
Keywords:
Status: NEW
Alias: CVE-2026-114690
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2563123 2563125 2563127 2563128
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-05-18 03:41 UTC by OSIDB Bzimport
Modified: 2026-10-28 19:29 UTC (History)
21 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-05-18 03:41:23 UTC
AI_ONLY_REPORT
package: gcc-toolset-15-gcc-15.2.1-7.el10
------
Summary: Confirmed out-of-bounds read/write in libstdc++ parallel  
`std::search` (`parallel/search.h`): undersized KMP border-table storage  
allows `_calc_borders()` to write `_advances[__pattern_length]`, and the  
full-match path then reads the same out-of-bounds slot, causing a process  
crash or other in-process memory-safety failure when the parallel search  
implementation is used.
Requirements to exploit: A consuming application must be built with  
libstdc++ parallel mode (`_GLIBCXX_PARALLEL`) and OpenMP, use random-access  
iterators, and reach the parallel `std::search` implementation. The  
attacker then needs control over the haystack and pattern so a full match  
occurs; the out-of-bounds write additionally requires `__pattern_length >  
1`, and normal reachability may depend on the parallel-search threshold  
unless the application forces parallel mode.
Component affected: `gcc-toolset-15-gcc-15.2.1-7.el10`, header-implemented  
libstdc++ parallel search in `libstdc++-v3/include/parallel/search.h`,  
primarily `_calc_borders()` and `_search_template()`.
Version affected: `gcc-toolset-15-gcc-15.2.1-7.el10` when applications are  
compiled with `_GLIBCXX_PARALLEL` and OpenMP and reach the parallel  
`std::search` implementation.
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 6.2 (MEDIUM)
AV:L - The confirmed issue is in a local library code path reached by a  
process using the affected headers; the available evidence does not  
establish a network-reachable attack surface in the package itself.
AC:L - Once the parallel search path is in use, a simple full-match  
input is sufficient to trigger the fault.
PR:N - No privileges are required beyond the ability to supply data to  
the affected code path.
UI:N - No separate user interaction is required after the vulnerable  
function is invoked.
S:U - The impact remains within the calling process.
C:N - No confidentiality impact has been demonstrated.
I:N - No integrity impact has been demonstrated.
A:H - The demonstrated outcome is an out-of-bounds access that can  
terminate the process.
Impact: Moderate. Red Hat rates issues as Moderate when they can affect  
confidentiality, integrity, or availability under certain circumstances or  
when a more serious bug class depends on an unlikely configuration. This  
issue is a confirmed memory-safety flaw with reproducible process-crash  
impact, but it depends on the non-default libstdc++ parallel-mode extension  
being enabled in consuming code and the current evidence supports  
process-level availability impact rather than privilege escalation or code  
execution.
Embargo: no
Reason: The issue is not default-reachable, the currently demonstrated  
impact is process crash/DoS, and affected consumers can mitigate by  
avoiding the parallel-mode path until a fix is available.
Acknowledgement: Aisle Research
Vulnerability Details: The parallel Knuth-Morris-Pratt search  
implementation allocates the border table with `__pattern_length` elements,  
but `_calc_borders()` writes through index `_length`. Later, when a full  
match is found, the post-match jump logic reads  
`__advances[__pattern_length]`. This creates a confirmed out-of-bounds  
write/read pair on the same array. The previously suspected `__splitters` /  
`omp_get_num_threads()` path was reviewed separately, but the available  
code shows allocation occurs after the actual team size is known in the  
`single` region, so this report is limited to the confirmed `__advances`  
off-by-one.
```cpp
template<typename _RAIter, typename _DifferenceTp>
void
__calc_borders(_RAIter __elements, _DifferenceTp __length,
_DifferenceTp* __off)
{
...
for (_DifferenceType __j = 2; __j <= __length; __j++)
{
...
_off[__j] = ++_k;
}
}
...
_DifferenceType __advances[__pattern_length];
_calc_borders(_begin2, __pattern_length, __advances);
...
if (__pos_in_pattern == __pattern_length)
{
...
__found_pattern = true;
break;
}
...
_start += (_pos_in_pattern - __advances[__pos_in_pattern]);
_pos_in_pattern = (_advances[__pos_in_pattern] < 0
? 0 : __advances[__pos_in_pattern]);
```
For `__pattern_length > 1`, the border-table construction writes one  
element past the end of the stack array. Independently, after a full match,  
the jump logic reads `__advances[__pattern_length]`. In testing, this is  
reproducible as a sanitizer-detected out-of-bounds access and can crash the  
process.
Steps to reproduce:
1. Use the following PoC, which forces the parallel strategy and creates a  
full match:
```cpp
#include <parallel/algorithm>
#include <parallel/settings.h>
#include <vector>
#include <iostream>
int main() {
__gnu_parallel::_Settings s = __gnu_parallel::_Settings::get();
s.algorithm_strategy = __gnu_parallel::force_parallel;
__gnu_parallel::_Settings::set(s);
std::vector<int> hay(5000, 1);              // >= search_minimal_n default
std::vector<int> pat{1,1,1,1,1,1,1,1};      // len >= 2, full matches
auto it = __gnu_parallel::search(hay.begin(), hay.end(), pat.begin(),  
pat.end());
std::cout << (it - hay.begin()) << "\n";
}
```
2. Build with GNU parallel mode, OpenMP, and AddressSanitizer:
`g++ -O1 -g -fsanitize=address -fopenmp -D_GLIBCXX_PARALLEL poc.cc -o  
poc`
3. Run with multiple threads:
`OMP_NUM_THREADS=4 ./poc`
4. Observe an AddressSanitizer out-of-bounds report originating in or near  
`parallel/search.h`, specifically `__calc_borders()` and/or the post-match  
jump logic.
Mitigation: Until a fixed package is available, avoid compiling  
untrusted-data paths with libstdc++ parallel mode (`_GLIBCXX_PARALLEL`) or  
avoid forcing the parallel `std::search` implementation in affected  
consumers. Because this logic is header-implemented, rebuilding affected  
applications without the parallel-mode extension removes the vulnerable  
code path.
Proposed Fix:
```diff
diff --git a/libstdc++-v3/include/parallel/search.h  
b/libstdc++-v3/include/parallel/search.h
@@
     _DifferenceType __advances[__pattern_length];
+      _DifferenceType __advances[__pattern_length + 1];
        _calc_borders(_begin2, __pattern_length, __advances);
```


This aligns the allocation with the algorithm's actual indexing range,  
which includes `0..__pattern_length`.
------
This report was generated using AI technology. Always review AI-generated  
content prior to use


Note You need to log in before you can comment on or make changes to this bug.