Bug 2563164 - CVE-2026-114691 gcc: Integer wrap in `std [fedora-all]
Summary: CVE-2026-114691 gcc: Integer wrap in `std [fedora-all]
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: rawhide
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: {"flaws": ["ccf7e0dc-596a-4c0b-bb6e-2...
Depends On:
Blocks: CVE-2026-114691
TreeView+ depends on / blocked
 
Reported: 2026-10-28 19:58 UTC by Marco Benatto
Modified: 2026-11-01 03:36 UTC (History)
12 users (show)

Fixed In Version: gcc-16.2.1-3.fc45 gcc-16.2.1-3.fc44
Clone Of:
Environment:
Last Closed: 2026-10-31 18:54:10 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Marco Benatto 2026-10-28 19:58:58 UTC
Disclaimer: Community trackers are created by Red Hat Product Security team on a best effort basis. Package maintainers are required to ascertain if the flaw indeed affects their package, before starting the update process.

AI_ONLY_REPORT
package: gcc-toolset-15-gcc-15.2.1-7.el10
------
Summary: Integer wrap in `std::vector<bool>` size-to-word conversion can  
bypass expected length checks in constructor/init paths:  
attacker-influenced near-`SIZE_MAX` lengths can wrap the internal  
word-count calculation, leave `vector<bool>` with inconsistent storage and  
logical size state, and later trigger undefined behavior or process  
termination.
Requirements to exploit: An attacker must be able to influence a very large  
element count passed into a `std::vector<bool>` constructor or  
initialization path in code built against the affected `libstdc++`  
implementation, then reach a follow-on operation such as `push_back` or  
`insert`. The exact result depends on allocator and build behavior.
Component affected: `gcc-toolset-15-gcc-15.2.1-7.el10`, specifically the  
`libstdc++` `std::vector<bool>` implementation in  
`libstdc++-v3/include/bits/stl_bvector.h` (`_S_nword`, constructor/init  
paths such as `vector(size_type, ...)` and `_M_initialize`)
Version affected: `gcc-toolset-15-gcc-15.2.1-7.el10`
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 issue is in a local library/container implementation, and no  
package-specific network-reachable path is established by the available  
evidence.
AC:L - Once a near-wrap size reaches the unchecked constructor/init  
path, the wrap and inconsistent state follow directly without a race or  
similarly uncommon prerequisite.
PR:N - No privileges are required beyond the ability to supply the size  
that reaches the affected code path.
UI:N - No separate user interaction is required.
S:U - The impact remains within the security scope of the consuming  
process.
C:N - The available evidence does not establish a reliable  
confidentiality impact.
I:N - The available evidence does not establish a reliable integrity  
impact beyond undefined behavior.
A:H - The inconsistent container state can lead to sanitizer-detected  
failures, crashes, or process termination in affected applications.
Impact: Moderate. Under Red Hat's severity guidance, this issue is harder  
to exploit than an easy privilege-gain or remote compromise flaw because it  
requires an unusual attacker-controlled near-maximum length to reach an  
unchecked constructor/init path. Even so, the reachable memory-unsafe state  
can still cause denial of service and other undefined behavior in affected  
applications, which is more than minimal impact.
Embargo: no
Reason: The current evidence supports a local, application-specific  
denial-of-service/undefined-behavior condition with demanding input  
preconditions. The record does not currently support a strong claim of easy  
remote compromise or a broadly wormable condition.
Acknowledgement: Aisle Research
Vulnerability Details: The issue is in the packed `std::vector<bool>`  
size-to-word conversion and its unchecked constructor/init path in  
`libstdc++-v3/include/bits/stl_bvector.h`:
```cpp
static size_t
_S_nword(size_t __n)
{ return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
...
vector(size_type __n, const bool& __value, const allocator_type& __a =  
allocator_type())
: Base(_a)
{
M_initialize(_n);
M_initialize_value(_value);
}
...
_Bit_pointer _q = this->_M_allocate(_n);
this->_M_impl._M_end_of_storage = __q + S_nword(_n);
iterator _start = iterator(std::addressof(*_q), 0);
this->_M_impl._M_start = __start;
this->_M_impl._M_finish = _start + difference_type(_n);
```
For very large `size_t` inputs, the addition inside `_S_nword` can wrap  
before division. In the affected constructor/init path, allocation and  
`_M_end_of_storage` then follow the wrapped word count, while `_M_finish`  
is advanced from the original requested element count. This can leave  
`std::vector<bool>` in an inconsistent state and later operations can  
encounter out-of-bounds behavior or other undefined behavior. By contrast,  
the available evidence indicates that `reserve` and related growth paths  
apply `max_size()` or `_M_check_len` guards, so the supported reachability  
claim here is the constructor/init path rather than `_M_reallocate` as a  
primary trigger.
Steps to reproduce:
1. Build a small test program against the affected `libstdc++`  
implementation with `-O0 -g -fsanitize=address,undefined`.
2. Use the following test case:
```cpp
#include <vector>
#include <limits>
int main() {
size_t n = std::numeric_limits<size_t>::max() - 31;
std::vector<bool> v(n, true);
v.push_back(false);
}
```
3. Run the program. On an affected build, the constructor can leave the  
container in an inconsistent state, and the subsequent `push_back` may  
trigger a sanitizer finding, crash, or other undefined-behavior symptom.  
The exact manifestation can vary by allocator and build configuration.
Mitigation: Reject externally influenced lengths long before `max_size()`  
or `SIZE_MAX` boundaries, especially for `std::vector<bool>` construction  
and initialization. Where untrusted size inputs are involved, prefer  
explicit application-level limits and avoid relying on the specialization's  
constructor/init path until a fix is applied.
Proposed Fix: A minimal fix is to add checked arithmetic in `_S_nword` and  
to apply constructor/init length validation before calling `_M_initialize`.
```diff
diff --git a/libstdc++-v3/include/bits/stl_bvector.h  
b/libstdc++-v3/include/bits/stl_bvector.h
@@
+#include <limits>
@@
static size_t
_S_nword(size_t __n)
     { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); }
+      {
+        constexpr size_t __wb = size_t(_S_word_bit);
+        if (_n > (std::numeric_limits<size_t>::max() - (_wb - 1)))
+          _throw_length_error(_N("vector<bool>: size overflow"));
+        return (_n + (_wb - 1)) / __wb;
+      }
@@
+      static size_type
+      _S_check_init_len(size_type __n, const allocator_type& __a)
+      {
+        const size_type __isize =
+          _gnu_cxx::numeric_traits<difference_type>::_max
+          - int(_S_word_bit) + 1;
+        const size_type __asize = _Bit_alloc_traits::max_size(
+          Bit_alloc_type(_a));
+        const size_type _max = (_asize <= __isize / int(_S_word_bit)
+          ? __asize * int(_S_word_bit) : __isize);
+        if (__n > __max)
+          _throw_length_error(_N("cannot create std::vector larger than  
max_size()"));
+        return __n;
+      }
@@

     : Base(_a)
+      : Base(_a)
        {

       M_initialize(_n);
+        M_initialize(_S_check_init_len(_n, __a));
          M_initialize_value(_value);
        }
@@

         M_initialize(_n);
+          M_initialize(_S_check_init_len(_n, _M_get_Bit_allocator()));
            std::copy(__first, __last, begin());
```


------
This report was generated using AI technology. Always review AI-generated  
content prior to use

Comment 1 Fedora Update System 2026-10-30 23:26:02 UTC
FEDORA-2026-589138efb1 (gcc-16.2.1-3.fc45) has been submitted as an update to Fedora 45.
https://bodhi.fedoraproject.org/updates/FEDORA-2026-589138efb1

Comment 2 Fedora Update System 2026-10-30 23:28:29 UTC
FEDORA-2026-d732fb97a0 (gcc-16.2.1-3.fc44) has been submitted as an update to Fedora 44.
https://bodhi.fedoraproject.org/updates/FEDORA-2026-d732fb97a0

Comment 3 Fedora Update System 2026-10-31 03:04:22 UTC
FEDORA-2026-d732fb97a0 has been pushed to the Fedora 44 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-d732fb97a0`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-d732fb97a0

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 4 Fedora Update System 2026-10-31 05:14:46 UTC
FEDORA-2026-589138efb1 has been pushed to the Fedora 45 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-589138efb1`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-589138efb1

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 5 Fedora Update System 2026-10-31 18:54:10 UTC
FEDORA-2026-589138efb1 (gcc-16.2.1-3.fc45) has been pushed to the Fedora 45 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 6 Fedora Update System 2026-11-01 03:36:39 UTC
FEDORA-2026-d732fb97a0 (gcc-16.2.1-3.fc44) has been pushed to the Fedora 44 stable repository.
If problem still persists, please make note of it in this bug report.


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