Bug 1342023 - Part 1: Remove ProtectedReallocPolicy from PageProtectingVector. r=jandem

This commit is contained in:
Emanuel Hoogeveen 2017-07-26 08:53:00 -04:00
parent e1e37e3e9c
commit 9f2123853d
2 changed files with 1 additions and 197 deletions

View File

@ -13,21 +13,8 @@
#include "mozilla/Types.h"
#include "mozilla/Vector.h"
#ifdef MALLOC_H
# include MALLOC_H
#endif
#include "ds/MemoryProtectionExceptionHandler.h"
#include "gc/Memory.h"
#include "js/Utility.h"
#ifdef MOZ_MEMORY
# ifdef XP_DARWIN
# define malloc_usable_size malloc_size
# else
extern "C" MFBT_API size_t malloc_usable_size(MALLOC_USABLE_SIZE_CONST_PTR void* p);
# endif
#endif
namespace js {
@ -467,189 +454,6 @@ PageProtectingVector<T, A, B, C, D, E, F, G>::appendSlow(const U* values, size_t
return appendNewBuffer(values, size);
}
class ProtectedReallocPolicy
{
uintptr_t currAddr;
size_t currSize;
uintptr_t prevAddr;
size_t prevSize;
static const uint8_t PoisonPattern = 0xe5;
template <typename T> void update(T* newAddr, size_t newSize) {
prevAddr = currAddr;
prevSize = currSize;
currAddr = uintptr_t(newAddr);
currSize = newSize * sizeof(T);
}
template <typename T> void updateIfValid(T* newAddr, size_t newSize) {
if (newAddr)
update<T>(newAddr, newSize);
}
template <typename T> T* reallocUpdate(T* oldAddr, size_t oldSize, size_t newSize) {
T* newAddr = js_pod_realloc<T>(oldAddr, oldSize, newSize);
updateIfValid<T>(newAddr, newSize);
return newAddr;
}
void crashWithInfo(const uint8_t* buffer, size_t bytes, const char* type) {
size_t start = 0;
while (start < bytes) {
if (MOZ_LIKELY(buffer[start] != PoisonPattern)) {
++start;
continue;
}
size_t limit;
for (limit = start + 1; limit < bytes && buffer[limit] == PoisonPattern; ++limit);
size_t size = limit - start;
if (size >= 16) {
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: %s buffer (old size = %" PRIu64
") contains %" PRIu64 " bytes of poison starting from"
" offset %" PRIu64 "!", type, uint64_t(bytes),
uint64_t(size), uint64_t(start));
}
start = limit;
}
MOZ_CRASH("Could not confirm the presence of poison!");
}
public:
ProtectedReallocPolicy() : currAddr(0), currSize(0), prevAddr(0), prevSize(0) {}
~ProtectedReallocPolicy() {
MOZ_RELEASE_ASSERT(!currSize && !currAddr);
}
template <typename T> T* maybe_pod_malloc(size_t numElems) {
MOZ_RELEASE_ASSERT(!currSize && !currAddr);
T* addr = js_pod_malloc<T>(numElems);
updateIfValid<T>(addr, numElems);
return addr;
}
template <typename T> T* maybe_pod_calloc(size_t numElems) {
MOZ_RELEASE_ASSERT(!currSize && !currAddr);
T* addr = js_pod_calloc<T>(numElems);
updateIfValid<T>(addr, numElems);
return addr;
}
template <typename T> T* maybe_pod_realloc(T* oldAddr, size_t oldSize, size_t newSize) {
if (uintptr_t(oldAddr) != currAddr) {
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: oldAddr and currAddr don't match "
"(0x%" PRIx64 " != 0x%" PRIx64 ", %" PRIu64 ")!",
uint64_t(oldAddr), uint64_t(currAddr), uint64_t(currSize));
}
if (oldSize * sizeof(T) != currSize) {
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: oldSize and currSize don't match "
"(%" PRIu64 " != %" PRIu64 ", 0x%" PRIx64 ")!",
uint64_t(oldSize * sizeof(T)), uint64_t(currSize),
uint64_t(currAddr));
}
MOZ_ASSERT_IF(oldAddr, oldSize);
if (MOZ_UNLIKELY(!newSize))
return nullptr;
if (MOZ_UNLIKELY(!oldAddr))
return maybe_pod_malloc<T>(newSize);
#ifdef MOZ_MEMORY
size_t usableSize = malloc_usable_size(oldAddr);
if (usableSize < currSize) {
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: usableSize < currSize "
"(%" PRIu64 " < %" PRIu64 ", %" PRIu64 ", %s)!",
uint64_t(usableSize), uint64_t(currSize),
uint64_t(prevSize), prevAddr == currAddr ? "true" : "false");
}
#endif
size_t bytes = (newSize >= oldSize ? oldSize : newSize) * sizeof(T);
// Check for the poison pattern every so often.
const uint8_t* oldAddrBytes = reinterpret_cast<const uint8_t*>(oldAddr);
for (size_t j, i = 0; i + 16 <= bytes; i += 1024) {
for (j = 0; j < 16 && oldAddrBytes[i + j] == PoisonPattern; ++j);
if (MOZ_UNLIKELY(j == 16))
crashWithInfo(oldAddrBytes, bytes, "old");
}
T* tmpAddr = js_pod_malloc<T>(newSize);
if (MOZ_UNLIKELY(!tmpAddr))
return reallocUpdate<T>(oldAddr, oldSize, newSize);
memcpy(tmpAddr, oldAddr, bytes);
const uint8_t* tmpAddrBytes = reinterpret_cast<const uint8_t*>(tmpAddr);
for (size_t j, i = 0; i + 16 <= bytes; i += 1024) {
for (j = 0; j < 16 && tmpAddrBytes[i + j] == PoisonPattern; ++j);
if (MOZ_UNLIKELY(j == 16))
crashWithInfo(tmpAddrBytes, bytes, "tmp");
}
if (!mozilla::PodEqual(oldAddrBytes, tmpAddrBytes, bytes))
MOZ_CRASH("maybe_pod_realloc: tmp buffer doesn't match old buffer!");
T* newAddr = js_pod_realloc<T>(oldAddr, oldSize, newSize);
if (MOZ_UNLIKELY(!newAddr)) {
js_free(tmpAddr);
return reallocUpdate<T>(oldAddr, oldSize, newSize);
}
const uint8_t* newAddrBytes = reinterpret_cast<const uint8_t*>(newAddr);
for (size_t j, i = 0; i + 16 <= bytes; i += 1024) {
for (j = 0; j < 16 && newAddrBytes[i + j] == PoisonPattern; ++j);
if (MOZ_UNLIKELY(j == 16))
crashWithInfo(newAddrBytes, bytes, "new");
}
if (!mozilla::PodEqual(tmpAddrBytes, newAddrBytes, bytes)) {
#ifdef MOZ_MEMORY
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: buffers don't match "
"(%" PRIu64 " >= %" PRIu64 ", %" PRIu64 ", %s)!",
uint64_t(usableSize), uint64_t(currSize),
uint64_t(prevSize), prevAddr == currAddr ? "true" : "false");
#else
MOZ_CRASH_UNSAFE_PRINTF("maybe_pod_realloc: buffers don't match "
"(%" PRIu64 ", %" PRIu64 ", %s)!",
uint64_t(currSize), uint64_t(prevSize),
prevAddr == currAddr ? "true" : "false");
#endif
}
js_free(tmpAddr);
update<T>(newAddr, newSize);
return newAddr;
}
template <typename T> T* pod_malloc(size_t numElems) { return maybe_pod_malloc<T>(numElems); }
template <typename T> T* pod_calloc(size_t numElems) { return maybe_pod_calloc<T>(numElems); }
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
return maybe_pod_realloc<T>(p, oldSize, newSize);
}
void free_(void* p) {
MOZ_RELEASE_ASSERT(uintptr_t(p) == currAddr);
#ifdef MOZ_MEMORY
size_t usableSize = malloc_usable_size(p);
if (usableSize < currSize) {
MOZ_CRASH_UNSAFE_PRINTF("free_: usableSize < currSize "
"(%" PRIu64 " < %" PRIu64 ", %" PRIu64 ", %s)!",
uint64_t(usableSize), uint64_t(currSize),
uint64_t(prevSize), prevAddr == currAddr ? "true" : "false");
}
#endif
js_free(p);
update<uint8_t>(0, 0);
}
void reportAllocOverflow() const {}
bool checkSimulatedOOM() const {
return !js::oom::ShouldFailWithOOM();
}
};
} /* namespace js */
#endif /* ds_PageProtectingVector_h */

View File

@ -182,7 +182,7 @@ namespace jit {
}
#ifndef RELEASE_OR_BETA
PageProtectingVector<unsigned char, 256, ProtectedReallocPolicy,
PageProtectingVector<unsigned char, 256, SystemAllocPolicy,
/* ProtectUsed = */ false, /* ProtectUnused = */ false> m_buffer;
#else
mozilla::Vector<unsigned char, 256, SystemAllocPolicy> m_buffer;