From 21361dbf741bc8bbf9371bc0465e3a1f82f74d2f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 5 Mar 2016 14:23:49 +0000 Subject: [PATCH] uclibc++: add a patch to fix memory corruption issues on exceptions Signed-off-by: Felix Fietkau SVN-Revision: 48928 --- .../patches/030-memory_corruption_fix.patch | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 package/libs/uclibc++/patches/030-memory_corruption_fix.patch diff --git a/package/libs/uclibc++/patches/030-memory_corruption_fix.patch b/package/libs/uclibc++/patches/030-memory_corruption_fix.patch new file mode 100644 index 00000000000..e34efdbb15b --- /dev/null +++ b/package/libs/uclibc++/patches/030-memory_corruption_fix.patch @@ -0,0 +1,114 @@ +From 1dc865b8bbb3911abc8ce53c7ae8a59dc90f6fc3 Mon Sep 17 00:00:00 2001 +From: Ivan Kold +Date: Thu, 3 Mar 2016 12:56:30 -0800 +Subject: [PATCH] Fix throw statement causing memory corruption + +The __cxxabiv1::__cxa_throw in the GCC's libsupc++ expects +sizeof(__cxa_refcounted_exception) bytes be allocated before +exception object. +uClibc++ allocates only sizeof(__cxa_exception) before an +exception object. +The __cxxabiv1::__cxa_throw writes in memory before allocated: +// gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:69 +__cxa_refcounted_exception *header + = __get_refcounted_exception_header_from_obj (obj); +header->referenceCount = 1; + +Signed-off-by: Ivan Kold +--- + include/unwind-cxx.h | 34 +++++++++++++++++++++++++++++++++- + src/eh_alloc.cpp | 8 ++++---- + 2 files changed, 37 insertions(+), 5 deletions(-) + +--- a/include/unwind-cxx.h ++++ b/include/unwind-cxx.h +@@ -1,5 +1,5 @@ + // -*- C++ -*- Exception handling and frame unwind runtime interface routines. +-// Copyright (C) 2001 Free Software Foundation, Inc. ++// Copyright (C) 2001-2015 Free Software Foundation, Inc. + // + // This file is part of GCC. + // +@@ -13,6 +13,10 @@ + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + // ++// Under Section 7 of GPL version 3, you are granted additional ++// permissions described in the GCC Runtime Library Exception, version ++// 3.1, as published by the Free Software Foundation. ++// + // You should have received a copy of the GNU General Public License + // along with GCC; see the file COPYING. If not, write to + // the Free Software Foundation, 59 Temple Place - Suite 330, +@@ -40,6 +44,12 @@ + #include + #include "unwind.h" + ++// Original unwind-cxx.h also includes bits/atomic_word.h which is CPU-specific, ++// but always defines _Atomic_word as typedef int . ++// Only thing that differs is memory-barrier macroses. ++typedef int _Atomic_word; ++ ++ + #pragma GCC visibility push(default) + + namespace __cxxabiv1 +@@ -79,6 +89,13 @@ struct __cxa_exception + _Unwind_Exception unwindHeader; + }; + ++struct __cxa_refcounted_exception ++{ ++ // Manage this header. ++ _Atomic_word referenceCount; ++ // __cxa_exception must be last, and no padding can be after it. ++ __cxa_exception exc; ++}; + + // A dependent C++ exception object consists of a header, which is a wrapper + // around an unwind object header with additional C++ specific information, +@@ -210,6 +227,21 @@ __get_exception_header_from_ue (_Unwind_ + return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; + } + ++// Acquire the C++ refcounted exception header from the C++ object. ++static inline __cxa_refcounted_exception * ++__get_refcounted_exception_header_from_obj (void *ptr) ++{ ++ return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; ++} ++ ++// Acquire the C++ refcounted exception header from the generic exception ++// header. ++static inline __cxa_refcounted_exception * ++__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) ++{ ++ return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; ++} ++ + } /* namespace __cxxabiv1 */ + + #pragma GCC visibility pop +--- a/src/eh_alloc.cpp ++++ b/src/eh_alloc.cpp +@@ -30,16 +30,16 @@ extern "C" void * __cxa_allocate_excepti + void *retval; + //The sizeof crap is required by Itanium ABI because we need to provide space for + //accounting information which is implementaion (gcc) specified +- retval = malloc (thrown_size + sizeof(__cxa_exception)); ++ retval = malloc (thrown_size + sizeof(__cxa_refcounted_exception)); + if (0 == retval){ + std::terminate(); + } +- memset (retval, 0, sizeof(__cxa_exception)); +- return (void *)((unsigned char *)retval + sizeof(__cxa_exception)); ++ memset (retval, 0, sizeof(__cxa_refcounted_exception)); ++ return (void *)((unsigned char *)retval + sizeof(__cxa_refcounted_exception)); + } + + extern "C" void __cxa_free_exception(void *vptr) throw(){ +- free( (char *)(vptr) - sizeof(__cxa_exception) ); ++ free( (char *)(vptr) - sizeof(__cxa_refcounted_exception) ); + } + + -- 2.30.2