/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/heap/trusted-range.cc
86 строк
4 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2023 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/heap/trusted-range.h" #include "src/heap/heap-inl.h" #include "src/utils/allocation.h" namespace v8 { namespace internal { #ifdef V8_ENABLE_SANDBOX bool TrustedRange::InitReservation(size_t requested) { DCHECK_LE(requested, kMaximalTrustedRangeSize); DCHECK_GE(requested, kMinimumTrustedRangeSize); auto page_allocator = GetPlatformPageAllocator(); const size_t kPageSize = NormalPage::kPageSize; CHECK(IsAligned(kPageSize, page_allocator->AllocatePageSize())); // We want the trusted range to be allocated above 4GB, for a few reasons: // 1. Certain (sandbox) bugs allow access to (only) the first 4GB of the // address space, so we don't want sensitive objects to live there. // 2. When pointers to trusted objects have the upper 32 bits cleared, they // may look like compressed pointers to some code in V8. For example, the // stack spill slot visiting logic (VisitSpillSlot in frames.cc) // currently assumes that when the top 32-bits are zero, then it's // dealing with a compressed pointer and will attempt to decompress them // with the main cage base, which in this case would break. // // To achieve this, we simply require 4GB alignment of the allocation and // assume that we can never map the zeroth page. const size_t base_alignment = size_t{4} * GB; const Address requested_start_hint = RoundDown(reinterpret_cast<Address>(page_allocator->GetRandomMmapAddr()), base_alignment); VirtualMemoryCage::ReservationParams params; params.page_allocator = page_allocator; params.reservation_size = requested; params.page_size = kPageSize; params.base_alignment = base_alignment; params.requested_start_hint = requested_start_hint; params.permissions = PageAllocator::Permission::kNoAccess; params.page_initialization_mode = base::PageInitializationMode::kAllocatedPagesCanBeUninitialized; params.page_freeing_mode = base::PageFreeingMode::kMakeInaccessible; bool success = VirtualMemoryCage::InitReservation(params); if (success) { // Reserve the null page to mitigate (compressed) nullptr dereference bugs. // // We typically use Smi::zero()/nullptr for protected pointer fields // (compressed pointers in trusted space) if the field is empty. // As such, we can have the equivalent of nullptr deref bugs if either some // code doesn't handle empty fields or if objects aren't correctly // initialized and fields are left empty. To mitigate these, we make the // first pages of trusted space inaccessible so that any access is // guaranteed to crash safely. size_t guard_region_size = 1 * MB; #if CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL guard_region_size = std::max(guard_region_size, kContiguousReadOnlyReservationSize); #endif // CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL DCHECK(IsAligned(guard_region_size, page_allocator_->AllocatePageSize())); CHECK(page_allocator_->AllocatePagesAt(base(), guard_region_size, PageAllocator::kNoAccess)); } #ifdef V8_ENABLE_SANDBOX_HARDWARE_SUPPORT // Sandboxed code should never write to trusted memory. SandboxHardwareSupport::RegisterOutOfSandboxMemory( base(), size(), PagePermissions::kNoAccess); #endif // V8_ENABLE_SANDBOX_HARDWARE_SUPPORT return success; } #endif // V8_ENABLE_SANDBOX } // namespace internal } // namespace v8