Commit 454272df authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Check poisoness only on 64bit archs.

On 64bit we guarantee that object alignment and sizes are multiple of
the default shadow memory granularity (8 bytes). The CL also introduces
CHECKs that the assumption holds.

Having kObjectAlignment be multiple of this granularity allows us to
check poisoness of each byte of an object. On 32bit we can not do that,
since the object alignment requirement is 4 bytes.

Bug: chromium:1241514
Change-Id: Ib19667724adaa7bc791ffa054eea618c365d65cb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3118552
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Auto-Submit: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76499}
parent c16c682e
......@@ -24,8 +24,9 @@
// Check that all bytes in a memory region are poisoned. This is different from
// `__asan_region_is_poisoned()` which only requires a single byte in the region
// to be poisoned.
#define ASAN_CHECK_MEMORY_REGION_IS_POISONED(start, size) \
// to be poisoned. Please note that the macro only works if both start and size
// are multiple of asan's shadow memory granularity.
#define ASAN_CHECK_WHOLE_MEMORY_REGION_IS_POISONED(start, size) \
do { \
for (size_t i = 0; i < size; i++) { \
CHECK(__asan_address_is_poisoned(reinterpret_cast<const char*>(start) + \
......@@ -47,7 +48,7 @@
#define ASAN_UNPOISON_MEMORY_REGION(start, size) \
ASAN_POISON_MEMORY_REGION(start, size)
#define ASAN_CHECK_MEMORY_REGION_IS_POISONED(start, size) \
#define ASAN_CHECK_WHOLE_MEMORY_REGION_IS_POISONED(start, size) \
ASAN_POISON_MEMORY_REGION(start, size)
#endif // !V8_USE_ADDRESS_SANITIZER
......
......@@ -117,7 +117,11 @@ V8_INLINE void CheckMemoryIsInaccessible(const void* address, size_t size) {
static_assert(!CheckMemoryIsInaccessibleIsNoop(),
"CheckMemoryIsInaccessibleIsNoop() needs to reflect "
"CheckMemoryIsInaccessible().");
ASAN_CHECK_MEMORY_REGION_IS_POISONED(address, size);
// Only check if memory is poisoned on 64 bit, since there we make sure that
// object sizes and alignments are multiple of shadow memory granularity.
#if defined(V8_TARGET_ARCH_64_BIT)
ASAN_CHECK_WHOLE_MEMORY_REGION_IS_POISONED(address, size);
#endif
ASAN_UNPOISON_MEMORY_REGION(address, size);
CheckMemoryIsZero(address, size);
ASAN_POISON_MEMORY_REGION(address, size);
......
......@@ -6,8 +6,11 @@
#include "src/base/lazy-instance.h"
#include "src/base/logging.h"
#include "src/base/macros.h"
#include "src/base/platform/platform.h"
#include "src/base/sanitizer/asan.h"
#include "src/heap/cppgc/gc-info-table.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/platform.h"
namespace cppgc {
......@@ -45,6 +48,17 @@ TracingController* Platform::GetTracingController() {
}
void InitializeProcess(PageAllocator* page_allocator) {
#if defined(V8_USE_ADDRESS_SANITIZER) && defined(V8_TARGET_ARCH_64_BIT)
// Retrieve asan's internal shadow memory granularity and check that Oilpan's
// object alignment/sizes are multiple of this granularity. This is needed to
// perform poisoness checks.
size_t shadow_scale;
__asan_get_shadow_mapping(&shadow_scale, nullptr);
DCHECK(shadow_scale);
const size_t poisoning_granularity = 1 << shadow_scale;
CHECK_EQ(0u, internal::kAllocationGranularity % poisoning_granularity);
#endif
CHECK(!g_page_allocator);
internal::GlobalGCInfoTable::Initialize(page_allocator);
g_page_allocator = page_allocator;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment