030-memory_corruption_fix.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. From 1dc865b8bbb3911abc8ce53c7ae8a59dc90f6fc3 Mon Sep 17 00:00:00 2001
  2. From: Ivan Kold <pixus.ru@gmail.com>
  3. Date: Thu, 3 Mar 2016 12:56:30 -0800
  4. Subject: [PATCH] Fix throw statement causing memory corruption
  5. The __cxxabiv1::__cxa_throw in the GCC's libsupc++ expects
  6. sizeof(__cxa_refcounted_exception) bytes be allocated before
  7. exception object.
  8. uClibc++ allocates only sizeof(__cxa_exception) before an
  9. exception object.
  10. The __cxxabiv1::__cxa_throw writes in memory before allocated:
  11. // gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:69
  12. __cxa_refcounted_exception *header
  13. = __get_refcounted_exception_header_from_obj (obj);
  14. header->referenceCount = 1;
  15. Signed-off-by: Ivan Kold <pixus.ru@gmail.com>
  16. ---
  17. include/unwind-cxx.h | 34 +++++++++++++++++++++++++++++++++-
  18. src/eh_alloc.cpp | 8 ++++----
  19. 2 files changed, 37 insertions(+), 5 deletions(-)
  20. --- a/include/unwind-cxx.h
  21. +++ b/include/unwind-cxx.h
  22. @@ -1,5 +1,5 @@
  23. // -*- C++ -*- Exception handling and frame unwind runtime interface routines.
  24. -// Copyright (C) 2001 Free Software Foundation, Inc.
  25. +// Copyright (C) 2001-2015 Free Software Foundation, Inc.
  26. //
  27. // This file is part of GCC.
  28. //
  29. @@ -13,6 +13,10 @@
  30. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31. // GNU General Public License for more details.
  32. //
  33. +// Under Section 7 of GPL version 3, you are granted additional
  34. +// permissions described in the GCC Runtime Library Exception, version
  35. +// 3.1, as published by the Free Software Foundation.
  36. +//
  37. // You should have received a copy of the GNU General Public License
  38. // along with GCC; see the file COPYING. If not, write to
  39. // the Free Software Foundation, 59 Temple Place - Suite 330,
  40. @@ -40,6 +44,12 @@
  41. #include <cstddef>
  42. #include "unwind.h"
  43. +// Original unwind-cxx.h also includes bits/atomic_word.h which is CPU-specific,
  44. +// but always defines _Atomic_word as typedef int .
  45. +// Only thing that differs is memory-barrier macroses.
  46. +typedef int _Atomic_word;
  47. +
  48. +
  49. #pragma GCC visibility push(default)
  50. namespace __cxxabiv1
  51. @@ -79,6 +89,13 @@ struct __cxa_exception
  52. _Unwind_Exception unwindHeader;
  53. };
  54. +struct __cxa_refcounted_exception
  55. +{
  56. + // Manage this header.
  57. + _Atomic_word referenceCount;
  58. + // __cxa_exception must be last, and no padding can be after it.
  59. + __cxa_exception exc;
  60. +};
  61. // A dependent C++ exception object consists of a header, which is a wrapper
  62. // around an unwind object header with additional C++ specific information,
  63. @@ -210,6 +227,21 @@ __get_exception_header_from_ue (_Unwind_
  64. return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
  65. }
  66. +// Acquire the C++ refcounted exception header from the C++ object.
  67. +static inline __cxa_refcounted_exception *
  68. +__get_refcounted_exception_header_from_obj (void *ptr)
  69. +{
  70. + return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1;
  71. +}
  72. +
  73. +// Acquire the C++ refcounted exception header from the generic exception
  74. +// header.
  75. +static inline __cxa_refcounted_exception *
  76. +__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc)
  77. +{
  78. + return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1;
  79. +}
  80. +
  81. } /* namespace __cxxabiv1 */
  82. #pragma GCC visibility pop
  83. --- a/src/eh_alloc.cpp
  84. +++ b/src/eh_alloc.cpp
  85. @@ -30,16 +30,16 @@ extern "C" void * __cxa_allocate_excepti
  86. void *retval;
  87. //The sizeof crap is required by Itanium ABI because we need to provide space for
  88. //accounting information which is implementaion (gcc) specified
  89. - retval = malloc (thrown_size + sizeof(__cxa_exception));
  90. + retval = malloc (thrown_size + sizeof(__cxa_refcounted_exception));
  91. if (0 == retval){
  92. std::terminate();
  93. }
  94. - memset (retval, 0, sizeof(__cxa_exception));
  95. - return (void *)((unsigned char *)retval + sizeof(__cxa_exception));
  96. + memset (retval, 0, sizeof(__cxa_refcounted_exception));
  97. + return (void *)((unsigned char *)retval + sizeof(__cxa_refcounted_exception));
  98. }
  99. extern "C" void __cxa_free_exception(void *vptr) throw(){
  100. - free( (char *)(vptr) - sizeof(__cxa_exception) );
  101. + free( (char *)(vptr) - sizeof(__cxa_refcounted_exception) );
  102. }