diff options
author | Josh Karlin <jkarlin@chromium.org> | 2021-04-14 09:21:00 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2021-05-07 08:27:06 +0000 |
commit | fdc2fda10577902e01078b27ad817031f758ed74 (patch) | |
tree | 7051689479b5121ae2e849cad4c41920e72b2a6f | |
parent | 4e0243666cd9821b619698aba17148a2844d1b25 (diff) | |
download | qtwebengine-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.cc | 10 |
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(); |