Commit ad9c395d authored by Samuel Groß's avatar Samuel Groß Committed by V8 LUCI CQ

Add LsanVirtualAddressSpace implementation

When leak sanitizer is active, an LsanVirtualAddressSpace is used and
takes care of marking the allocated pages as lsan root regions.

Bug: chromium:1276767
Change-Id: I3d8a61f7d3c59e4574e46707d2217031a32e3f0e
Cq-Include-Trybots: luci.v8.try:v8_linux64_heap_sandbox_dbg_ng,v8_linux_arm64_sim_heap_sandbox_dbg_ng
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3314828
Commit-Queue: Samuel Groß <saelo@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78251}
parent 2d087f23
......@@ -1926,6 +1926,8 @@ filegroup(
"src/base/sanitizer/asan.h",
"src/base/sanitizer/lsan-page-allocator.cc",
"src/base/sanitizer/lsan-page-allocator.h",
"src/base/sanitizer/lsan-virtual-address-space.cc",
"src/base/sanitizer/lsan-virtual-address-space.h",
"src/base/sanitizer/msan.h",
"src/base/sanitizer/tsan.h",
"src/snapshot/code-serializer.cc",
......
......@@ -5040,6 +5040,8 @@ v8_component("v8_libbase") {
"src/base/sanitizer/asan.h",
"src/base/sanitizer/lsan-page-allocator.cc",
"src/base/sanitizer/lsan-page-allocator.h",
"src/base/sanitizer/lsan-virtual-address-space.cc",
"src/base/sanitizer/lsan-virtual-address-space.h",
"src/base/sanitizer/lsan.h",
"src/base/sanitizer/msan.h",
"src/base/sanitizer/tsan.h",
......
// Copyright 2021 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/base/sanitizer/lsan-virtual-address-space.h"
#include "include/v8-platform.h"
#include "src/base/logging.h"
#if defined(LEAK_SANITIZER)
#include <sanitizer/lsan_interface.h>
#endif
namespace v8 {
namespace base {
LsanVirtualAddressSpace::LsanVirtualAddressSpace(
std::unique_ptr<v8::VirtualAddressSpace> vas)
: VirtualAddressSpace(vas->page_size(), vas->allocation_granularity(),
vas->base(), vas->size()),
vas_(std::move(vas)) {
DCHECK_NOT_NULL(vas_);
}
Address LsanVirtualAddressSpace::AllocatePages(Address hint, size_t size,
size_t alignment,
PagePermissions permissions) {
Address result = vas_->AllocatePages(hint, size, alignment, permissions);
#if defined(LEAK_SANITIZER)
if (result != 0) {
__lsan_register_root_region(reinterpret_cast<void*>(result), size);
}
#endif // defined(LEAK_SANITIZER)
return result;
}
bool LsanVirtualAddressSpace::FreePages(Address address, size_t size) {
bool result = vas_->FreePages(address, size);
#if defined(LEAK_SANITIZER)
if (result) {
__lsan_unregister_root_region(reinterpret_cast<void*>(address), size);
}
#endif // defined(LEAK_SANITIZER)
return result;
}
std::unique_ptr<VirtualAddressSpace> LsanVirtualAddressSpace::AllocateSubspace(
Address hint, size_t size, size_t alignment,
PagePermissions max_permissions) {
auto subspace =
vas_->AllocateSubspace(hint, size, alignment, max_permissions);
#if defined(LEAK_SANITIZER)
if (subspace) {
subspace = std::make_unique<LsanVirtualAddressSpace>(std::move(subspace));
}
#endif // defined(LEAK_SANITIZER)
return subspace;
}
} // namespace base
} // namespace v8
// Copyright 2021 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.
#ifndef V8_BASE_SANITIZER_LSAN_VIRTUAL_ADDRESS_SPACE_H_
#define V8_BASE_SANITIZER_LSAN_VIRTUAL_ADDRESS_SPACE_H_
#include "include/v8-platform.h"
#include "src/base/base-export.h"
#include "src/base/compiler-specific.h"
namespace v8 {
namespace base {
using Address = uintptr_t;
// This is a v8::VirtualAddressSpace implementation that decorates provided page
// allocator object with leak sanitizer notifications when LEAK_SANITIZER is
// defined.
class V8_BASE_EXPORT LsanVirtualAddressSpace final
: public v8::VirtualAddressSpace {
public:
explicit LsanVirtualAddressSpace(
std::unique_ptr<v8::VirtualAddressSpace> vas);
~LsanVirtualAddressSpace() override = default;
void SetRandomSeed(int64_t seed) override {
return vas_->SetRandomSeed(seed);
}
Address RandomPageAddress() override { return vas_->RandomPageAddress(); }
Address AllocatePages(Address hint, size_t size, size_t alignment,
PagePermissions permissions) override;
bool FreePages(Address address, size_t size) override;
bool SetPagePermissions(Address address, size_t size,
PagePermissions permissions) override {
return vas_->SetPagePermissions(address, size, permissions);
}
bool CanAllocateSubspaces() override { return vas_->CanAllocateSubspaces(); }
std::unique_ptr<VirtualAddressSpace> AllocateSubspace(
Address hint, size_t size, size_t alignment,
PagePermissions max_permissions) override;
bool DiscardSystemPages(Address address, size_t size) override {
return vas_->DiscardSystemPages(address, size);
}
bool DecommitPages(Address address, size_t size) override {
return vas_->DecommitPages(address, size);
}
private:
std::unique_ptr<v8::VirtualAddressSpace> vas_;
};
} // namespace base
} // namespace v8
#endif // V8_BASE_SANITIZER_LSAN_VIRTUAL_ADDRESS_SPACE_H_
......@@ -14,6 +14,7 @@
#include "src/base/platform/platform.h"
#include "src/base/platform/wrappers.h"
#include "src/base/sanitizer/lsan-page-allocator.h"
#include "src/base/sanitizer/lsan-virtual-address-space.h"
#include "src/base/vector.h"
#include "src/base/virtual-address-space.h"
#include "src/flags/flags.h"
......@@ -86,7 +87,12 @@ v8::PageAllocator* GetPlatformPageAllocator() {
}
v8::VirtualAddressSpace* GetPlatformVirtualAddressSpace() {
#if defined(LEAK_SANITIZER)
static base::LeakyObject<base::LsanVirtualAddressSpace> vas(
std::make_unique<base::VirtualAddressSpace>());
#else
static base::LeakyObject<base::VirtualAddressSpace> vas;
#endif
return vas.get();
}
......
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