@@ -75,6 +75,7 @@ SRC_URI = "${BASEURI} \
file://0028-fix-gcc-libitm-false-postives-02.patch \
file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \
file://0001-mapper-localhost-might-not-be-known.patch \
+ file://0029-CVE-2026-95619.patch \
"
UNPACKDIR = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/sources"
new file mode 100644
@@ -0,0 +1,187 @@
+From 59d235ffa5a69231eb42e5290d52dc8c90d28b7a Mon Sep 17 00:00:00 2001
+From: Jonathan Wakely <jwakely@redhat.com>
+Date: Wed, 23 Sep 2026 13:15:18 +0100
+Subject: libstdc++: Ensure that aligned new detects size_t overflow
+ (CVE-2026-95619)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Depending on the implementation used for aligned new, we might need to
+round the size argument up to a multiple of the alignment. If either the
+size or the alignment is a huge value then the rounded result could
+wraparound to a small value which would then be successfully allocated
+by the underlying libc allocation function. This means that we return a
+non-null pointer but not of the requested size. Instead we should throw
+std::bad_alloc because the allocation cannot succeed.
+
+This doesn't affect most modern targets because they use the
+posix_memalign implementation, which doesn't do that rounding.
+
+On targets without posix_memalign we use C11 aligned_alloc and round
+before calling it. That rounding needs to be checked for overflow. The
+using-directive for ::aligned_alloc is replaced with a new
+__gnu_cxx::aligned_alloc function and the existing fix-ups for that path
+are moved from operator new into the new function, with added check for
+the overflow we need to fix.
+
+On *-*-mingw* we use the Windows _aligned_malloc function which
+correctly checks for overflow on Windows. But the Wine version of that
+function does not and has the same overflow problem so we need to do our
+own checks before calling it. We include a conservative 2*sizeof(void*)
+adjustment in our own overflow check.
+
+On targets without any aligned allocation function we provide our own
+__gnu_cxx::aligned_alloc in terms of malloc. This also needs an overflow
+check.
+
+libstdc++-v3/ChangeLog:
+
+ * libsupc++/new_opa.cc
+ [_GLIBCXX_HAVE_ALIGNED_ALLOC] (__gnu_cxx::aligned_alloc):
+ Replace using-directive with new function. Check for size_t
+ overflow.
+ [_GLIBCXX_HAVE__ALIGNED_MALLOC] (__gnu_cxx::aligned_alloc):
+ Check for size_t overflow.
+ (__gnu_cxx::aligned_alloc): Likewise in fallback definition.
+ (operator new) [_GLIBCXX_HAVE_ALIGNED_ALLOC]: Move parameter
+ adjustments to new __gnu_cxx::aligned_alloc function.
+ * testsuite/18_support/new_aligned_wrap.cc: New test.
+
+CVE: CVE-2026-95619
+
+Upstream-Status: Backport [https://gcc.gnu.org/cgit/gcc/patch/?id=59d235ffa5a69231eb42e5290d52dc8c90d28b7a]
+
+Reviewed-by: Tomasz KamiĆski <tkaminsk@redhat.com>
+Signed-off-by: Hemanth Kumar M D <Hemanth.KumarMD@windriver.com>
+---
+ libstdc++-v3/libsupc++/new_opa.cc | 49 ++++++++++++++--------
+ .../testsuite/18_support/new_aligned_wrap.cc | 39 +++++++++++++++++
+ 2 files changed, 71 insertions(+), 17 deletions(-)
+ create mode 100644 libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc
+
+diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
+index 7bda847a9257..bd0098ac09e4 100644
+--- a/libstdc++-v3/libsupc++/new_opa.cc
++++ b/libstdc++-v3/libsupc++/new_opa.cc
+@@ -81,12 +81,38 @@ aligned_alloc (std::size_t al, std::size_t sz)
+ return nullptr;
+ }
+ #elif _GLIBCXX_HAVE_ALIGNED_ALLOC
+-using ::aligned_alloc;
++// We have C11 aligned_alloc but we need to satisfy its preconditions.
++static inline void*
++aligned_alloc (std::size_t al, std::size_t sz)
++{
++# if defined _AIX || defined __APPLE__
++ /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement
++ * that alignment is a multiple of sizeof(void*).
++ * OS X 10.15 has the same requirement. */
++ if (al < sizeof(void*))
++ al = sizeof(void*);
++# endif
++ /* C11: the value of size shall be an integral multiple of alignment. */
++ if (__builtin_add_overflow(sz, al - 1, &sz)) [[unlikely]]
++ return nullptr;
++ sz &= ~(al - 1);
++ return ::aligned_alloc(al, sz);
++}
+ #elif _GLIBCXX_HAVE__ALIGNED_MALLOC
++// Use Windows _aligned_malloc
+ static inline void*
+ aligned_alloc (std::size_t al, std::size_t sz)
+-{ return _aligned_malloc(sz, al); }
++{
++ // The Wine msvcrt.dll version of _aligned_malloc doesn't detect overflow
++ // so do it ourselves. We know al + 2 * sizeof(void*) won't overflow because
++ // has_single_bit(al) was already checked by the caller.
++ std::size_t check;
++ if (__builtin_add_overflow(sz, al + 2 * sizeof(void*), &check)) [[unlikely]]
++ return nullptr;
++ return _aligned_malloc(sz, al);
++}
+ #elif _GLIBCXX_HAVE_MEMALIGN
++// Use memalign (and assume that what it returns can be passed to free).
+ static inline void*
+ aligned_alloc (std::size_t al, std::size_t sz)
+ {
+@@ -103,8 +129,10 @@ aligned_alloc (std::size_t al, std::size_t sz)
+ // We need extra bytes to store the original value returned by malloc.
+ if (al < sizeof(void*))
+ al = sizeof(void*);
+- void* const malloc_ptr = malloc(sz + al);
+- if (!malloc_ptr)
++ if (__builtin_add_overflow(sz, al, &sz)) [[unlikely]]
++ return nullptr;
++ void* const malloc_ptr = malloc(sz);
++ if (!malloc_ptr) [[unlikely]]
+ return nullptr;
+ // Align to the requested value, leaving room for the original malloc value.
+ void* const aligned_ptr = (void *) (((uintptr_t) malloc_ptr + al) & -al);
+@@ -131,19 +159,6 @@ operator new (std::size_t sz, std::align_val_t al)
+ if (__builtin_expect (sz == 0, false))
+ sz = 1;
+
+-#if _GLIBCXX_HAVE_POSIX_MEMALIGN
+-#elif _GLIBCXX_HAVE_ALIGNED_ALLOC
+-# if defined _AIX || defined __APPLE__
+- /* AIX 7.2.0.0 aligned_alloc incorrectly has posix_memalign's requirement
+- * that alignment is a multiple of sizeof(void*).
+- * OS X 10.15 has the same requirement. */
+- if (align < sizeof(void*))
+- align = sizeof(void*);
+-# endif
+- /* C11: the value of size shall be an integral multiple of alignment. */
+- sz = (sz + align - 1) & ~(align - 1);
+-#endif
+-
+ void *p;
+
+ while ((p = __gnu_cxx::aligned_alloc (align, sz)) == nullptr)
+diff --git a/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc b/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc
+new file mode 100644
+index 000000000000..dbd642d6ba58
+--- /dev/null
++++ b/libstdc++-v3/testsuite/18_support/new_aligned_wrap.cc
+@@ -0,0 +1,39 @@
++// { dg-do run }
++
++#include <new>
++#include <stdint.h>
++#include <testsuite_hooks.h>
++
++#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
++
++void
++check_aligned_new_overflow(std::size_t size, std::size_t align)
++{
++#if __cpp_aligned_new
++ std::align_val_t alignv = (std::align_val_t)align;
++ try
++ {
++ (void) ::operator new(size, alignv);
++ VERIFY(false);
++ }
++ catch (const std::bad_alloc&)
++ {
++ }
++
++ void* p = ::operator new(size, alignv, std::nothrow);
++ VERIFY(p == 0);
++#endif
++}
++
++int main()
++{
++ check_aligned_new_overflow(-9, 32);
++ check_aligned_new_overflow(SIZE_MAX, 8);
++ check_aligned_new_overflow(SIZE_MAX, 32);
++ check_aligned_new_overflow(SIZE_MAX, 1024);
++ check_aligned_new_overflow(SIZE_MAX, 65536);
++ check_aligned_new_overflow(SIZE_MAX - 1, 16);
++ check_aligned_new_overflow(SIZE_MAX - 1025, 1024);
++ check_aligned_new_overflow(SIZE_MAX - 1024, 1024);
++ check_aligned_new_overflow(SIZE_MAX - 65536, 65536);
++}
+--
+cgit