diff options
author | Kostya Kortchinsky <kostyak@google.com> | 2017-08-16 16:40:48 +0000 |
---|---|---|
committer | Kostya Kortchinsky <kostyak@google.com> | 2017-08-16 16:40:48 +0000 |
commit | f1b1a7775f722048d4914c73d0a631890c9d5de3 (patch) | |
tree | 178ba2b99a9a1d05a1201ace236cc1804a07eb25 /lib/scudo/scudo_allocator.cpp | |
parent | bcb584b2636e6acc02aba4c8a8d8b07fac4c537c (diff) |
[scudo] Application & platform compatibility changes
Summary:
This patch changes a few (small) things around for compatibility purposes for
the current Android & Fuchsia work:
- `realloc`'ing some memory that was not allocated with `malloc`, `calloc` or
`realloc`, while UB according to http://pubs.opengroup.org/onlinepubs/009695399/functions/realloc.html
is more common that one would think. We now only check this if
`DeallocationTypeMismatch` is set; change the "mismatch" error
messages to be more homogeneous;
- some sketchily written but widely used libraries expect a call to `realloc`
to copy the usable size of the old chunk to the new one instead of the
requested size. We have to begrundingly abide by this de-facto standard.
This doesn't seem to impact security either way, unless someone comes up with
something we didn't think about;
- the CRC32 intrinsics for 64-bit take a 64-bit first argument. This is
misleading as the upper 32 bits end up being ignored. This was also raising
`-Wconversion` errors. Change things to take a `u32` as first argument.
This also means we were (and are) only using 32 bits of the Cookie - not a
big thing, but worth mentioning.
- Includes-wise: prefer `stddef.h` to `cstddef`, move `scudo_flags.h` where it
is actually needed.
- Add tests for the memalign-realloc case, and the realloc-usable-size one.
(Edited typos)
Reviewers: alekseyshl
Reviewed By: alekseyshl
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36754
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@311018 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/scudo/scudo_allocator.cpp')
-rw-r--r-- | lib/scudo/scudo_allocator.cpp | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/lib/scudo/scudo_allocator.cpp b/lib/scudo/scudo_allocator.cpp index e1758568b..4f87d3523 100644 --- a/lib/scudo/scudo_allocator.cpp +++ b/lib/scudo/scudo_allocator.cpp @@ -16,6 +16,7 @@ #include "scudo_allocator.h" #include "scudo_crc32.h" +#include "scudo_flags.h" #include "scudo_tls.h" #include "scudo_utils.h" @@ -35,7 +36,7 @@ static uptr Cookie; // at compilation or at runtime. static atomic_uint8_t HashAlgorithm = { CRC32Software }; -INLINE u32 computeCRC32(uptr Crc, uptr Value, uptr *Array, uptr ArraySize) { +INLINE u32 computeCRC32(u32 Crc, uptr Value, uptr *Array, uptr ArraySize) { // If the hardware CRC32 feature is defined here, it was enabled everywhere, // as opposed to only for scudo_crc32.cpp. This means that other hardware // specific instructions were likely emitted at other places, and as a @@ -87,7 +88,8 @@ struct ScudoChunk : UnpackedHeader { ZeroChecksumHeader.Checksum = 0; uptr HeaderHolder[sizeof(UnpackedHeader) / sizeof(uptr)]; memcpy(&HeaderHolder, &ZeroChecksumHeader, sizeof(HeaderHolder)); - u32 Crc = computeCRC32(Cookie, reinterpret_cast<uptr>(this), HeaderHolder, + u32 Crc = computeCRC32(static_cast<u32>(Cookie), + reinterpret_cast<uptr>(this), HeaderHolder, ARRAY_SIZE(HeaderHolder)); return static_cast<u16>(Crc); } @@ -514,8 +516,8 @@ struct ScudoAllocator { if (Header.AllocType != Type) { // With the exception of memalign'd Chunks, that can be still be free'd. if (Header.AllocType != FromMemalign || Type != FromMalloc) { - dieWithMessage("ERROR: allocation type mismatch on address %p\n", - UserPtr); + dieWithMessage("ERROR: allocation type mismatch when deallocating " + "address %p\n", UserPtr); } } } @@ -546,9 +548,11 @@ struct ScudoAllocator { dieWithMessage("ERROR: invalid chunk state when reallocating address " "%p\n", OldPtr); } - if (UNLIKELY(OldHeader.AllocType != FromMalloc)) { - dieWithMessage("ERROR: invalid chunk type when reallocating address %p\n", - OldPtr); + if (DeallocationTypeMismatch) { + if (UNLIKELY(OldHeader.AllocType != FromMalloc)) { + dieWithMessage("ERROR: allocation type mismatch when reallocating " + "address %p\n", OldPtr); + } } uptr UsableSize = Chunk->getUsableSize(&OldHeader); // The new size still fits in the current chunk, and the size difference @@ -567,7 +571,7 @@ struct ScudoAllocator { if (NewPtr) { uptr OldSize = OldHeader.FromPrimary ? OldHeader.SizeOrUnusedBytes : UsableSize - OldHeader.SizeOrUnusedBytes; - memcpy(NewPtr, OldPtr, Min(NewSize, OldSize)); + memcpy(NewPtr, OldPtr, Min(NewSize, UsableSize)); quarantineOrDeallocateChunk(Chunk, &OldHeader, OldSize); } return NewPtr; |