Commit b87d408f authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[heap-profiler] Fix a use-after-free when snapshots are deleted

If a caller starts the sampling heap profiler and takes a snapshot, and
then deletes the snapshot before the sampling has completed, a
use-after-free will occur on the StringsStorage pointer.

The same issue applies for StartTrackingHeapObjects which shares the
same StringsStorage object.

Bug: v8:8373
Change-Id: I5d69d60d3f9465f9dd3b3bef107c204e0fda0643
Reviewed-on: https://chromium-review.googlesource.com/c/1301477
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarAlexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57114}
parent 767b152a
......@@ -23,9 +23,14 @@ HeapProfiler::~HeapProfiler() = default;
void HeapProfiler::DeleteAllSnapshots() {
snapshots_.clear();
names_.reset(new StringsStorage());
MaybeClearStringsStorage();
}
void HeapProfiler::MaybeClearStringsStorage() {
if (snapshots_.empty() && !sampling_heap_profiler_ && !allocation_tracker_) {
names_.reset(new StringsStorage());
}
}
void HeapProfiler::RemoveSnapshot(HeapSnapshot* snapshot) {
snapshots_.erase(
......@@ -126,6 +131,7 @@ bool HeapProfiler::StartSamplingHeapProfiler(
void HeapProfiler::StopSamplingHeapProfiler() {
sampling_heap_profiler_.reset();
MaybeClearStringsStorage();
}
......@@ -159,6 +165,7 @@ void HeapProfiler::StopHeapObjectsTracking() {
ids_->StopHeapObjectsTracking();
if (allocation_tracker_) {
allocation_tracker_.reset();
MaybeClearStringsStorage();
heap()->RemoveHeapObjectAllocationTracker(this);
}
}
......
......@@ -92,6 +92,8 @@ class HeapProfiler : public HeapObjectAllocationTracker {
v8::PersistentValueVector<v8::Object>* objects);
private:
void MaybeClearStringsStorage();
Heap* heap() const;
// Mapping from HeapObject addresses to objects' uids.
......
......@@ -3920,3 +3920,45 @@ TEST(WeakReference) {
const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot();
CHECK(ValidateSnapshot(snapshot));
}
TEST(Bug8373_1) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
heap_profiler->StartSamplingHeapProfiler(100);
heap_profiler->TakeHeapSnapshot();
// Causes the StringsStorage to be deleted.
heap_profiler->DeleteAllHeapSnapshots();
// Triggers an allocation sample that tries to use the StringsStorage.
for (int i = 0; i < 2 * 1024; ++i) {
CompileRun(
"new Array(64);"
"new Uint8Array(16);");
}
heap_profiler->StopSamplingHeapProfiler();
}
TEST(Bug8373_2) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
heap_profiler->StartTrackingHeapObjects(true);
heap_profiler->TakeHeapSnapshot();
// Causes the StringsStorage to be deleted.
heap_profiler->DeleteAllHeapSnapshots();
// Triggers an allocations that try to use the StringsStorage.
for (int i = 0; i < 2 * 1024; ++i) {
CompileRun(
"new Array(64);"
"new Uint8Array(16);");
}
heap_profiler->StopTrackingHeapObjects();
}
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