mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1332594 - Part 2: Check AssemblerBuffer for corruption during realloc. r=jandem
--HG-- extra : rebase_source : fb8936ce4035fb5aac2894b084e6dd34e0a18085
This commit is contained in:
parent
984d697b47
commit
bdb07b0aba
@ -8,6 +8,7 @@
|
||||
#define ds_PageProtectingVector_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include "ds/MemoryProtectionExceptionHandler.h"
|
||||
@ -454,11 +455,6 @@ PageProtectingVector<T, A, B, C, D, E, F, G>::appendSlow(const U* values, size_t
|
||||
|
||||
class ProtectedReallocPolicy
|
||||
{
|
||||
/* We hardcode the page size here to minimize administrative overhead. */
|
||||
static const size_t pageShift = 12;
|
||||
static const size_t pageSize = 1 << pageShift;
|
||||
static const size_t pageMask = pageSize - 1;
|
||||
|
||||
public:
|
||||
template <typename T> T* maybe_pod_malloc(size_t numElems) {
|
||||
return js_pod_malloc<T>(numElems);
|
||||
@ -468,35 +464,34 @@ class ProtectedReallocPolicy
|
||||
}
|
||||
template <typename T> T* maybe_pod_realloc(T* oldAddr, size_t oldSize, size_t newSize) {
|
||||
MOZ_ASSERT_IF(oldAddr, oldSize);
|
||||
MOZ_ASSERT(gc::SystemPageSize() == pageSize);
|
||||
if (MOZ_UNLIKELY(!newSize))
|
||||
return nullptr;
|
||||
if (MOZ_UNLIKELY(!oldAddr))
|
||||
return js_pod_malloc<T>(newSize);
|
||||
|
||||
T* newAddr = nullptr;
|
||||
size_t initPage = (uintptr_t(oldAddr - 1) >> pageShift) + 1;
|
||||
size_t lastPage = (uintptr_t(oldAddr + oldSize) >> pageShift) - 1;
|
||||
size_t toCopy = (newSize >= oldSize ? oldSize : newSize) * sizeof(T);
|
||||
if (MOZ_UNLIKELY(oldSize >= 32 * 1024 && lastPage >= initPage)) {
|
||||
T* protectAddr = reinterpret_cast<T*>(initPage << pageShift);
|
||||
size_t protectSize = (lastPage - initPage + 1) << pageShift;
|
||||
MemoryProtectionExceptionHandler::addRegion(protectAddr, protectSize);
|
||||
gc::MakePagesReadOnly(protectAddr, protectSize);
|
||||
newAddr = js_pod_malloc<T>(newSize);
|
||||
if (MOZ_LIKELY(newAddr))
|
||||
memcpy(newAddr, oldAddr, toCopy);
|
||||
gc::UnprotectPages(protectAddr, protectSize);
|
||||
MemoryProtectionExceptionHandler::removeRegion(protectAddr);
|
||||
if (MOZ_LIKELY(newAddr))
|
||||
js_free(oldAddr);
|
||||
} else {
|
||||
newAddr = js_pod_malloc<T>(newSize);
|
||||
if (MOZ_LIKELY(newAddr)) {
|
||||
memcpy(newAddr, oldAddr, toCopy);
|
||||
js_free(oldAddr);
|
||||
}
|
||||
T* tmpAddr = js_pod_malloc<T>(newSize);
|
||||
if (MOZ_UNLIKELY(!tmpAddr))
|
||||
return js_pod_realloc<T>(oldAddr, oldSize, newSize);
|
||||
|
||||
size_t bytes = (newSize >= oldSize ? oldSize : newSize) * sizeof(T);
|
||||
memcpy(tmpAddr, oldAddr, bytes);
|
||||
|
||||
T* newAddr = js_pod_realloc<T>(oldAddr, oldSize, newSize);
|
||||
if (MOZ_UNLIKELY(!newAddr)) {
|
||||
js_free(tmpAddr);
|
||||
return js_pod_realloc<T>(oldAddr, oldSize, newSize);
|
||||
}
|
||||
|
||||
const uint8_t* newAddrBytes = reinterpret_cast<const uint8_t*>(newAddr);
|
||||
const uint8_t* tmpAddrBytes = reinterpret_cast<const uint8_t*>(tmpAddr);
|
||||
if (!mozilla::PodEqual(tmpAddrBytes, newAddrBytes, bytes)) {
|
||||
if (oldAddr == newAddr)
|
||||
MOZ_CRASH("New buffer doesn't match the old buffer (newAddr == oldAddr)!");
|
||||
else
|
||||
MOZ_CRASH("New buffer doesn't match the old buffer (newAddr != oldAddr)!");
|
||||
}
|
||||
|
||||
js_free(tmpAddr);
|
||||
return newAddr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user