From e6cdf34116305bae21caeff1738625ce375bc196 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 10 Mar 2015 20:43:34 +0000 Subject: [PATCH] [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 llvm-svn: 231839 --- libcxxabi/src/cxa_personality.cpp | 32 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index 3ea8ca34c3f3..24838f428f4c 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include "config.h" @@ -141,6 +142,19 @@ Notes: namespace __cxxabiv1 { +namespace +{ + +template +uintptr_t readPointerHelper(const uint8_t*& p) { + AsType value; + memcpy(&value, const_cast(p), sizeof(AsType)); + p += sizeof(AsType); + return static_cast(value); +} + +} // end namespace + extern "C" { @@ -245,28 +259,22 @@ readEncodedPointer(const uint8_t** data, uint8_t encoding) result = static_cast(readSLEB128(&p)); break; case DW_EH_PE_udata2: - result = *((uint16_t*)p); - p += sizeof(uint16_t); + result = readPointerHelper(p); break; case DW_EH_PE_udata4: - result = *((uint32_t*)p); - p += sizeof(uint32_t); + result = readPointerHelper(p); break; case DW_EH_PE_udata8: - result = static_cast(*((uint64_t*)p)); - p += sizeof(uint64_t); + result = readPointerHelper(p); break; case DW_EH_PE_sdata2: - result = static_cast(*((int16_t*)p)); - p += sizeof(int16_t); + result = readPointerHelper(p); break; case DW_EH_PE_sdata4: - result = static_cast(*((int32_t*)p)); - p += sizeof(int32_t); + result = readPointerHelper(p); break; case DW_EH_PE_sdata8: - result = static_cast(*((int64_t*)p)); - p += sizeof(int64_t); + result = readPointerHelper(p); break; default: // not supported