summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Karlin <jkarlin@chromium.org>2021-04-14 09:21:00 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-05-07 08:27:06 +0000
commitfdc2fda10577902e01078b27ad817031f758ed74 (patch)
tree7051689479b5121ae2e849cad4c41920e72b2a6f
parent4e0243666cd9821b619698aba17148a2844d1b25 (diff)
downloadqtwebengine-chromium-fdc2fda10577902e01078b27ad817031f758ed74.tar.gz
[Backport] CVE-2021-21214: Use after free in Network API
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2727306: Fix removal of observers in NetworkStateNotifier The NetworkStateNotifier has a per-thread list of observer pointers. If one is deleted mid-iteration, what we do is replace the pointer in the list with a 0, and add the index to the zeroed list of observers to remove after iteration completes. Well, the removal step was broken for cases where there were multiple elements to remove. It didn't adjust for the fact that the indexes shifted after each removal. Bug: 1170148 Change-Id: I446acaae5f8a805a58142848634a0ee8c5f90882 Reviewed-by: Kentaro Hara <haraken@chromium.org> Commit-Queue: Josh Karlin <jkarlin@chromium.org> Cr-Commit-Position: refs/heads/master@{#858853} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc
index 4a22c312362..c37c1c87f89 100644
--- a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc
+++ b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc
@@ -362,8 +362,14 @@ void NetworkStateNotifier::CollectZeroedObservers(
// If any observers were removed during the iteration they will have
// 0 values, clean them up.
- for (size_t i = 0; i < list->zeroed_observers.size(); ++i)
- list->observers.EraseAt(list->zeroed_observers[i]);
+ std::sort(list->zeroed_observers.begin(), list->zeroed_observers.end());
+ int removed = 0;
+ for (size_t i = 0; i < list->zeroed_observers.size(); ++i) {
+ int index_to_remove = list->zeroed_observers[i] - removed;
+ DCHECK_EQ(nullptr, list->observers[index_to_remove]);
+ list->observers.EraseAt(index_to_remove);
+ removed += 1;
+ }
list->zeroed_observers.clear();