已开启
fix CVE-2026-102010,CVE-2026-95619 #747
m0_74032979创建于 21 天前
fix CVE-2026-102010,CVE-2026-95619 #747
已开启
共 3 个文件变更+258-1
| @@ -0,0 +1,61 @@ | |||
| 1 | +From aaa8351f4d2e636f9680a1f0a8ebc2f0a60611e6 Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Jonathan Wakely <jwakely@redhat.com> | ||
| 3 | +Date: Fri, 25 Sep 2026 18:14:34 +0100 | ||
| 4 | +Subject: [PATCH] libstdc++: Fix use-after-free in pbds binary heap | ||
| 5 | + (CVE-2026-102010) [PR127656] | ||
| 6 | + | ||
| 7 | +After reallocating the storage the m_a_entries pointer is left dangling | ||
| 8 | +and the new storage is leaked. | ||
| 9 | + | ||
| 10 | +libstdc++-v3/ChangeLog: | ||
| 11 | + | ||
| 12 | + PR libstdc++/127656 | ||
| 13 | + * include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp | ||
| 14 | + (erase_if): Update m_a_entries after reallocation. | ||
| 15 | + * testsuite/ext/pb_ds/regression/priority_queues_erase_if.cc: | ||
| 16 | + New test. | ||
| 17 | + | ||
| 18 | +Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> | ||
| 19 | +--- | ||
| 20 | + .../detail/binary_heap_/erase_fn_imps.hpp | 1 + | ||
| 21 | + .../regression/priority_queues_erase_if.cc | 19 +++++++++++++++++++ | ||
| 22 | + 2 files changed, 20 insertions(+) | ||
| 23 | + create mode 100644 libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues_erase_if.cc | ||
| 24 | + | ||
| 25 | +diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp | ||
| 26 | +index 2e70ed5c663d4..80d2cccbbf0b1 100644 | ||
| 27 | +--- a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp | ||
| 28 | ++++ b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp | ||
| 29 | +@@ -121,6 +121,7 @@ erase_if(Pred pred) | ||
| 30 | + entry_pointer new_entries = s_entry_allocator.allocate(new_size); | ||
| 31 | + std::copy(m_a_entries, m_a_entries + left, new_entries); | ||
| 32 | + s_entry_allocator.deallocate(m_a_entries, m_actual_size); | ||
| 33 | ++ m_a_entries = new_entries; | ||
| 34 | + m_actual_size = new_size; | ||
| 35 | + resize_policy::notify_arbitrary(m_actual_size); | ||
| 36 | + } | ||
| 37 | +diff --git a/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues_erase_if.cc b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues_erase_if.cc | ||
| 38 | +new file mode 100644 | ||
| 39 | +index 0000000000000..30b8452eff969 | ||
| 40 | +--- /dev/null | ||
| 41 | ++++ b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues_erase_if.cc | ||
| 42 | +@@ -0,0 +1,19 @@ | ||
| 43 | ++// { dg-do run } | ||
| 44 | ++ | ||
| 45 | ++// CVE-2026-201020 use-after-free in binary heap erase_if | ||
| 46 | ++ | ||
| 47 | ++#include <ext/pb_ds/priority_queue.hpp> | ||
| 48 | ++ | ||
| 49 | ++bool is_odd(int v) { return v & 1; } | ||
| 50 | ++ | ||
| 51 | ++int main() | ||
| 52 | ++{ | ||
| 53 | ++ using __gnu_pbds::priority_queue; | ||
| 54 | ++ using __gnu_pbds::binary_heap_tag; | ||
| 55 | ++ priority_queue<int, std::less<int>, binary_heap_tag> q; | ||
| 56 | ++ q.push(1); | ||
| 57 | ++ q.push(2); | ||
| 58 | ++ q.push(3); | ||
| 59 | ++ q.erase_if(&is_odd); | ||
| 60 | ++ q.clear(); | ||
| 61 | ++} | ||
| @@ -0,0 +1,188 @@ | |||
| 1 | +From 59d235ffa5a69231eb42e5290d52dc8c90d28b7a Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: Jonathan Wakely <jwakely@redhat.com> | ||
| 3 | +Date: Wed, 23 Sep 2026 13:15:18 +0100 | ||
| 4 | +Subject: [PATCH] libstdc++: Ensure that aligned new detects size_t overflow | ||
| 5 | + (CVE-2026-95619) | ||
| 6 | +MIME-Version: 1.0 | ||
| 7 | +Content-Type: text/plain; charset=UTF-8 | ||
| 8 | +Content-Transfer-Encoding: 8bit | ||
| 9 | + | ||
| 10 | +Depending on the implementation used for aligned new, we might need to | ||
| 11 | +round the size argument up to a multiple of the alignment. If either the | ||
| 12 | +size or the alignment is a huge value then the rounded result could | ||
| 13 | +wraparound to a small value which would then be successfully allocated | ||
| 14 | +by the underlying libc allocation function. This means that we return a | ||
| 15 | +non-null pointer but not of the requested size. Instead we should throw | ||
| 16 | +std::bad_alloc because the allocation cannot succeed. | ||
| 17 | + | ||
| 18 | +This doesn't affect most modern targets because they use the | ||
| 19 | +posix_memalign implementation, which doesn't do that rounding. | ||
| 20 | + | ||
| 21 | +On targets without posix_memalign we use C11 aligned_alloc and round | ||
| 22 | +before calling it. That rounding needs to be checked for overflow. The | ||
| 23 | +using-directive for ::aligned_alloc is replaced with a new | ||
| 24 | +__gnu_cxx::aligned_alloc function and the existing fix-ups for that path | ||
| 25 | +are moved from operator new into the new function, with added check for | ||
| 26 | +the overflow we need to fix. | ||
| 27 | + | ||
| 28 | +On *-*-mingw* we use the Windows _aligned_malloc function which | ||
| 29 | +correctly checks for overflow on Windows. But the Wine version of that | ||
| 30 | +function does not and has the same overflow problem so we need to do our | ||
| 31 | +own checks before calling it. We include a conservative 2*sizeof(void*) | ||
| 32 | +adjustment in our own overflow check. | ||
| 33 | + | ||
| 34 | +On targets without any aligned allocation function we provide our own | ||
| 35 | +__gnu_cxx::aligned_alloc in terms of malloc. This also needs an overflow | ||
| 36 | +check. | ||
| 37 | + | ||
| 38 | +libstdc++-v3/ChangeLog: | ||
| 39 | + | ||
| 40 | + * libsupc++/new_opa.cc | ||
| 41 | + [_GLIBCXX_HAVE_ALIGNED_ALLOC] (__gnu_cxx::aligned_alloc): | ||
| 42 | + Replace using-directive with new function. Check for size_t | ||
| 43 | + overflow. | ||
| 44 | + [_GLIBCXX_HAVE__ALIGNED_MALLOC] (__gnu_cxx::aligned_alloc): | ||
| 45 | + Check for size_t overflow. | ||
| 46 | + (__gnu_cxx::aligned_alloc): Likewise in fallback definition. | ||
| 47 | + (operator new) [_GLIBCXX_HAVE_ALIGNED_ALLOC]: Move parameter | ||
| 48 | + adjustments to new __gnu_cxx::aligned_alloc function. | ||
| 49 | + * testsuite/18_support/new_aligned_wrap.cc: New test. | ||
| 50 | + | ||
| 51 | +Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com> | ||
| 52 | +--- | ||
| 53 | + libstdc++-v3/libsupc++/new_opa.cc | 48 ++++++++++++------- | ||
| 54 | + .../testsuite/18_support/new_aligned_wrap.cc | 39 +++++++++++++++ | ||
| 55 | + 2 files changed, 71 insertions(+), 16 deletions(-) | ||
| 56 | + create mode 100644 libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc | ||
| 57 | + | ||
| 58 | +diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc | ||
| 59 | +index 411cd8d98..b00f32f0b 100644 | ||
| 60 | +--- a/libstdc++-v3/libsupc++/new_opa.cc | ||
| 61 | ++++ b/libstdc++-v3/libsupc++/new_opa.cc | ||
| 62 | +@@ -64,11 +64,36 @@ extern "C" | ||
| 63 | + | ||
| 64 | + namespace __gnu_cxx { | ||
| 65 | + #if _GLIBCXX_HAVE_ALIGNED_ALLOC | ||
| 66 | +-using ::aligned_alloc; | ||
| 67 | ++// We have C11 aligned_alloc but we need to satisfy its preconditions. | ||
| 68 | ++static inline void* | ||
| 69 | ++aligned_alloc (std::size_t al, std::size_t sz) | ||
| 70 | ++{ | ||
| 71 | ++# if defined _AIX || defined __APPLE__ | ||
| 72 | ++ /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement | ||
| 73 | ++ * that alignment is a multiple of sizeof(void*). | ||
| 74 | ++ * OS X 10.15 has the same requirement. */ | ||
| 75 | ++ if (al < sizeof(void*)) | ||
| 76 | ++ al = sizeof(void*); | ||
| 77 | ++# endif | ||
| 78 | ++ /* C11: the value of size shall be an integral multiple of alignment. */ | ||
| 79 | ++ if (__builtin_add_overflow(sz, al - 1, &sz)) [[__unlikely__]] | ||
| 80 | ++ return nullptr; | ||
| 81 | ++ sz &= ~(al - 1); | ||
| 82 | ++ return ::aligned_alloc(al, sz); | ||
| 83 | ++} | ||
| 84 | + #elif _GLIBCXX_HAVE__ALIGNED_MALLOC | ||
| 85 | ++// Use Windows _aligned_malloc | ||
| 86 | + static inline void* | ||
| 87 | + aligned_alloc (std::size_t al, std::size_t sz) | ||
| 88 | +-{ return _aligned_malloc(sz, al); } | ||
| 89 | ++{ | ||
| 90 | ++ // The Wine msvcrt.dll version of _aligned_malloc doesn't detect overflow | ||
| 91 | ++ // so do it ourselves. We know al + 2 * sizeof(void*) won't overflow because | ||
| 92 | ++ // has_single_bit(al) was already checked by the caller. | ||
| 93 | ++ std::size_t check; | ||
| 94 | ++ if (__builtin_add_overflow(sz, al + 2 * sizeof(void*), &check)) [[__unlikely__]] | ||
| 95 | ++ return nullptr; | ||
| 96 | ++ return _aligned_malloc(sz, al); | ||
| 97 | ++} | ||
| 98 | + #elif _GLIBCXX_HAVE_POSIX_MEMALIGN | ||
| 99 | + static inline void* | ||
| 100 | + aligned_alloc (std::size_t al, std::size_t sz) | ||
| 101 | +@@ -84,6 +109,7 @@ aligned_alloc (std::size_t al, std::size_t sz) | ||
| 102 | + return nullptr; | ||
| 103 | + } | ||
| 104 | + #elif _GLIBCXX_HAVE_MEMALIGN | ||
| 105 | ++// Use memalign (and assume that what it returns can be passed to free). | ||
| 106 | + static inline void* | ||
| 107 | + aligned_alloc (std::size_t al, std::size_t sz) | ||
| 108 | + { | ||
| 109 | +@@ -100,8 +126,10 @@ aligned_alloc (std::size_t al, std::size_t sz) | ||
| 110 | + // We need extra bytes to store the original value returned by malloc. | ||
| 111 | + if (al < sizeof(void*)) | ||
| 112 | + al = sizeof(void*); | ||
| 113 | +- void* const malloc_ptr = malloc(sz + al); | ||
| 114 | +- if (!malloc_ptr) | ||
| 115 | ++ if (__builtin_add_overflow(sz, al, &sz)) [[__unlikely__]] | ||
| 116 | ++ return nullptr; | ||
| 117 | ++ void* const malloc_ptr = malloc(sz); | ||
| 118 | ++ if (!malloc_ptr) [[__unlikely__]] | ||
| 119 | + return nullptr; | ||
| 120 | + // Align to the requested value, leaving room for the original malloc value. | ||
| 121 | + void* const aligned_ptr = (void *) (((uintptr_t) malloc_ptr + al) & -al); | ||
| 122 | +@@ -128,18 +156,6 @@ operator new (std::size_t sz, std::align_val_t al) | ||
| 123 | + if (__builtin_expect (sz == 0, false)) | ||
| 124 | + sz = 1; | ||
| 125 | + | ||
| 126 | +-#if _GLIBCXX_HAVE_ALIGNED_ALLOC | ||
| 127 | +-# if defined _AIX || defined __APPLE__ | ||
| 128 | +- /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement | ||
| 129 | +- * that alignment is a multiple of sizeof(void*). | ||
| 130 | +- * OS X 10.15 has the same requirement. */ | ||
| 131 | +- if (align < sizeof(void*)) | ||
| 132 | +- align = sizeof(void*); | ||
| 133 | +-# endif | ||
| 134 | +- /* C11: the value of size shall be an integral multiple of alignment. */ | ||
| 135 | +- sz = (sz + align - 1) & ~(align - 1); | ||
| 136 | +-#endif | ||
| 137 | +- | ||
| 138 | + void *p; | ||
| 139 | + | ||
| 140 | + while ((p = __gnu_cxx::aligned_alloc (align, sz)) == nullptr) | ||
| 141 | +diff --git a/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc b/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc | ||
| 142 | +new file mode 100644 | ||
| 143 | +index 000000000..873a7ca1a | ||
| 144 | +--- /dev/null | ||
| 145 | ++++ b/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc | ||
| 146 | +@@ -0,0 +1,39 @@ | ||
| 147 | ++// { dg-do run } | ||
| 148 | ++ | ||
| 149 | ++#include <new> | ||
| 150 | ++#include <stdint.h> | ||
| 151 | ++#include <testsuite_hooks.h> | ||
| 152 | ++ | ||
| 153 | ++#pragma GCC diagnostic ignored "-Walloc-size-larger-than=" | ||
| 154 | ++ | ||
| 155 | ++void | ||
| 156 | ++check_aligned_new_overflow(std::size_t size, std::size_t align) | ||
| 157 | ++{ | ||
| 158 | ++#if __cpp_aligned_new | ||
| 159 | ++ std::align_val_t alignv = (std::align_val_t)align; | ||
| 160 | ++ try | ||
| 161 | ++ { | ||
| 162 | ++ (void) ::operator new(size, alignv); | ||
| 163 | ++ VERIFY(false); | ||
| 164 | ++ } | ||
| 165 | ++ catch (const std::bad_alloc&) | ||
| 166 | ++ { | ||
| 167 | ++ } | ||
| 168 | ++ | ||
| 169 | ++ void* p = ::operator new(size, alignv, std::nothrow); | ||
| 170 | ++ VERIFY(p == 0); | ||
| 171 | ++#endif | ||
| 172 | ++} | ||
| 173 | ++ | ||
| 174 | ++int main() | ||
| 175 | ++{ | ||
| 176 | ++ check_aligned_new_overflow(-9, 32); | ||
| 177 | ++ check_aligned_new_overflow(SIZE_MAX, 8); | ||
| 178 | ++ check_aligned_new_overflow(SIZE_MAX, 32); | ||
| 179 | ++ check_aligned_new_overflow(SIZE_MAX, 1024); | ||
| 180 | ++ check_aligned_new_overflow(SIZE_MAX, 65536); | ||
| 181 | ++ check_aligned_new_overflow(SIZE_MAX - 1, 16); | ||
| 182 | ++ check_aligned_new_overflow(SIZE_MAX - 1025, 1024); | ||
| 183 | ++ check_aligned_new_overflow(SIZE_MAX - 1024, 1024); | ||
| 184 | ++ check_aligned_new_overflow(SIZE_MAX - 65536, 65536); | ||
| 185 | ++} | ||
| 186 | +-- | ||
| 187 | +2.43.0 | ||
| 188 | + | ||
| @@ -2,7 +2,7 @@ | |||
| 2 | %global gcc_major 12 | 2 | %global gcc_major 12 |
| 3 | # Note, gcc_release must be integer, if you want to add suffixes to | 3 | # Note, gcc_release must be integer, if you want to add suffixes to |
| 4 | # %%{release}, append them after %%{gcc_release} on Release: line. | 4 | # %%{release}, append them after %%{gcc_release} on Release: line. |
| 5 | -%global gcc_release 115 | 5 | +%global gcc_release 116 |
| 6 | 6 | ||
| 7 | %global _unpackaged_files_terminate_build 0 | 7 | %global _unpackaged_files_terminate_build 0 |
| 8 | %global _performance_build 1 | 8 | %global _performance_build 1 |
| @@ -540,6 +540,8 @@ Patch427: 0427-Backport-i386-Fix-some-c86-4g-m7-reservations.patch | |||
| 540 | Patch428: 0428-Backport-i386-Adjust-c86-4g-m7-512-bit-memory-costs.patch | 540 | Patch428: 0428-Backport-i386-Adjust-c86-4g-m7-512-bit-memory-costs.patch |
| 541 | Patch429: 0429-Backport-i386-Add-HYGON-c86-4g-m8-support.patch | 541 | Patch429: 0429-Backport-i386-Add-HYGON-c86-4g-m8-support.patch |
| 542 | Patch430: 0430-Backport-AArch64-SVE-memcpy-and-memset-expansion.patch | 542 | Patch430: 0430-Backport-AArch64-SVE-memcpy-and-memset-expansion.patch |
| 543 | +Patch431: 0431-Backport-CVE-2026-102010.patch | ||
| 544 | +Patch432: 0432-Backport-CVE-2026-95619.patch | ||
| 543 | 545 | ||
| 544 | # Part 1001-1999 | 546 | # Part 1001-1999 |
| 545 | Patch1001: 0001-Sw64-Port-add-configure-support-for-sw64.patch | 547 | Patch1001: 0001-Sw64-Port-add-configure-support-for-sw64.patch |
| @@ -1845,6 +1847,8 @@ not stable, so plugins must be rebuilt any time GCC is updated. | |||
| 1845 | %patch -P428 -p1 | 1847 | %patch -P428 -p1 |
| 1846 | %patch -P429 -p1 | 1848 | %patch -P429 -p1 |
| 1847 | %patch -P430 -p1 | 1849 | %patch -P430 -p1 |
| 1850 | +%patch -P431 -p1 | ||
| 1851 | +%patch -P432 -p1 | ||
| 1848 | 1852 | ||
| 1849 | %ifarch sw_64 | 1853 | %ifarch sw_64 |
| 1850 | %patch -P1001 -p1 | 1854 | %patch -P1001 -p1 |
| @@ -4561,6 +4565,10 @@ end | |||
| 4561 | %doc rpm.doc/changelogs/libcc1/ChangeLog* | 4565 | %doc rpm.doc/changelogs/libcc1/ChangeLog* |
| 4562 | 4566 | ||
| 4563 | %changelog | 4567 | %changelog |
| 4568 | +* Thu Oct 8 2026 zhengzongmin <zhengzongmin@xfusion.com> - 12.3.1-116 | ||
| 4569 | +- Type: Sync | ||
| 4570 | +- DESC: Sync patches for CVE-2026-102010 and CVE-2026-95619 | ||
| 4571 | + | ||
| 4564 | * Thu Aug 27 2026 yly97 <yelingyun1@h-partners.com> - 12.3.1-115 | 4572 | * Thu Aug 27 2026 yly97 <yelingyun1@h-partners.com> - 12.3.1-115 |
| 4565 | - Type: Sync | 4573 | - Type: Sync |
| 4566 | - DESC: Add SVE memcpy and memset expansion | 4574 | - DESC: Add SVE memcpy and memset expansion |