From 95f2f82f7d6e1abcce940a448c180fe6eb9e1ae1 Mon Sep 17 00:00:00 2001 From: Victor Gomes Date: Mon, 31 May 2021 13:16:54 +0200 Subject: [PATCH] [Backport] CVE-2021-30541: Use after free in V8 Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/3067222: Fix GC issue in BuildJsonObject We must ensure that the sweeper is not running or has already swept mutable_double_buffer. Otherwise the GC can add it to the free list. (cherry picked from commit 81181a8ad80ac978a6a8732d05f615c645df95d2) Bug: v8:11837 Bug: chromium:1214842 No-Try: true No-Presubmit: true No-Tree-Checks: true Change-Id: Ifd9cf15f1c94f664fd6489c70bb38b59730cdd78 Commit-Queue: Victor Gomes Cr-Original-Commit-Position: refs/heads/master@{#74859} Commit-Queue: Roger Felipe Zanoni da Silva Reviewed-by: Achuith Bhandarkar Reviewed-by: Jana Grill Cr-Commit-Position: refs/branch-heads/9.0@{#68} Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1} Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001} Reviewed-by: Allan Sandfeld Jensen --- chromium/v8/src/heap/heap.cc | 4 ++++ chromium/v8/src/heap/heap.h | 2 ++ chromium/v8/src/json/json-parser.cc | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/chromium/v8/src/heap/heap.cc b/chromium/v8/src/heap/heap.cc index e6cef6bd858a..3da993f7a251 100644 --- a/chromium/v8/src/heap/heap.cc +++ b/chromium/v8/src/heap/heap.cc @@ -2117,6 +2117,10 @@ void Heap::CompleteSweepingYoung(GarbageCollector collector) { array_buffer_sweeper()->EnsureFinished(); } +void Heap::EnsureSweepingCompleted() { + mark_compact_collector()->EnsureSweepingCompleted(); +} + void Heap::UpdateCurrentEpoch(GarbageCollector collector) { if (IsYoungGenerationCollector(collector)) { epoch_young_ = next_epoch(); diff --git a/chromium/v8/src/heap/heap.h b/chromium/v8/src/heap/heap.h index b1ccc4391ebc..3db1fa5fabf2 100644 --- a/chromium/v8/src/heap/heap.h +++ b/chromium/v8/src/heap/heap.h @@ -1068,6 +1068,8 @@ class Heap { void CompleteSweepingFull(); void CompleteSweepingYoung(GarbageCollector collector); + void EnsureSweepingCompleted(); + IncrementalMarking* incremental_marking() { return incremental_marking_.get(); } diff --git a/chromium/v8/src/json/json-parser.cc b/chromium/v8/src/json/json-parser.cc index 668cd79824dd..faaa7317b452 100644 --- a/chromium/v8/src/json/json-parser.cc +++ b/chromium/v8/src/json/json-parser.cc @@ -620,6 +620,11 @@ Handle JsonParser::BuildJsonObject( DCHECK_EQ(mutable_double_address, end); } #endif + // Before setting the length of mutable_double_buffer back to zero, we + // must ensure that the sweeper is not running or has already swept the + // object's page. Otherwise the GC can add the contents of + // mutable_double_buffer to the free list. + isolate()->heap()->EnsureSweepingCompleted(); mutable_double_buffer->set_length(0); } }