summaryrefslogtreecommitdiff
path: root/src/cxa_personality.cpp
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2015-03-10 20:43:34 +0000
committerEric Fiselier <eric@efcs.ca>2015-03-10 20:43:34 +0000
commit89ea9ad0b0a48a9b9fccf6de81bdca1861960855 (patch)
tree80e7757e6997beda6a18de10ee41dcad079d1880 /src/cxa_personality.cpp
parentfd4c54b4b43f9f652a76ed433262807539628d08 (diff)
[libcxx] Fix PR21580 - Undefined behavior in readEncodedPointer()
Summary: This patch fixes a bug in `readEncodedPointer()` where it would read from memory that was not suitably aligned. This patch fixes it by using memcpy. Reviewers: danalbert, echristo, compnerd, mclow.lists Reviewed By: compnerd, mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D8179 git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@231839 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'src/cxa_personality.cpp')
-rw-r--r--src/cxa_personality.cpp32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/cxa_personality.cpp b/src/cxa_personality.cpp
index 3ea8ca3..24838f4 100644
--- a/src/cxa_personality.cpp
+++ b/src/cxa_personality.cpp
@@ -14,6 +14,7 @@
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include <typeinfo>
#include "config.h"
@@ -141,6 +142,19 @@ Notes:
namespace __cxxabiv1
{
+namespace
+{
+
+template <class AsType>
+uintptr_t readPointerHelper(const uint8_t*& p) {
+ AsType value;
+ memcpy(&value, const_cast<uint8_t*>(p), sizeof(AsType));
+ p += sizeof(AsType);
+ return static_cast<uintptr_t>(value);
+}
+
+} // end namespace
+
extern "C"
{
@@ -245,28 +259,22 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding)
result = static_cast<uintptr_t>(readSLEB128(&p));
break;
case DW_EH_PE_udata2:
- result = *((uint16_t*)p);
- p += sizeof(uint16_t);
+ result = readPointerHelper<uint16_t>(p);
break;
case DW_EH_PE_udata4:
- result = *((uint32_t*)p);
- p += sizeof(uint32_t);
+ result = readPointerHelper<uint32_t>(p);
break;
case DW_EH_PE_udata8:
- result = static_cast<uintptr_t>(*((uint64_t*)p));
- p += sizeof(uint64_t);
+ result = readPointerHelper<uint64_t>(p);
break;
case DW_EH_PE_sdata2:
- result = static_cast<uintptr_t>(*((int16_t*)p));
- p += sizeof(int16_t);
+ result = readPointerHelper<int16_t>(p);
break;
case DW_EH_PE_sdata4:
- result = static_cast<uintptr_t>(*((int32_t*)p));
- p += sizeof(int32_t);
+ result = readPointerHelper<int32_t>(p);
break;
case DW_EH_PE_sdata8:
- result = static_cast<uintptr_t>(*((int64_t*)p));
- p += sizeof(int64_t);
+ result = readPointerHelper<int64_t>(p);
break;
default:
// not supported