mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1342023 - Part 1: Remove ProtectedReallocPolicy from PageProtectingVector. r=jandem
This commit is contained in:
parent
e1e37e3e9c
commit
9f2123853d
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user