summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReilly Grant <reillyg@chromium.org>2020-07-23 22:35:03 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2020-07-29 10:55:46 +0000
commite402452015f408085a061e5f5c12b7e765f9796e (patch)
treea270a7531769f8741f3fe23e5560b5c90742f87d
parentda24a7f8bcb62406c1b21e3b0635f9cea6b13553 (diff)
downloadqtwebengine-chromium-e402452015f408085a061e5f5c12b7e765f9796e.tar.gz
[Backport] CVE-2020-6541: Use after free in WebUSB
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/2304538: usb: Prevent iterator invalidation during Promise resolution This change swaps sets of ScriptPromiseResolvers into local variables in a number of places where it was possible for script to execute during the call to Resolve() or Reject() and modify the set being iterated over, thus invalidating the iterator. (cherry picked from commit dbc6c3c3652680e287c60b3c6551622748543439) Bug: 1106773 Change-Id: Id4eb0cd444a7dbb5de23038ec80f44fee649cfe4 Auto-Submit: Reilly Grant <reillyg@chromium.org> Commit-Queue: James Hollyer <jameshollyer@chromium.org> Reviewed-by: James Hollyer <jameshollyer@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#790217} Reviewed-by: Reilly Grant <reillyg@chromium.org> Cr-Commit-Position: refs/branch-heads/4147@{#931} Cr-Branched-From: 16307825352720ae04d898f37efa5449ad68b606-refs/heads/master@{#768962} Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc15
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb_device.cc8
2 files changed, 17 insertions, 6 deletions
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
index cbe336ae699..ce38760e569 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -264,15 +264,22 @@ void USB::OnDeviceRemoved(UsbDeviceInfoPtr device_info) {
void USB::OnServiceConnectionError() {
service_.reset();
client_receiver_.reset();
- for (ScriptPromiseResolver* resolver : get_devices_requests_)
+
+ // Move the set to a local variable to prevent script execution in Resolve()
+ // from invalidating the iterator used by the loop.
+ HeapHashSet<Member<ScriptPromiseResolver>> get_devices_requests;
+ get_devices_requests.swap(get_devices_requests_);
+ for (auto& resolver : get_devices_requests)
resolver->Resolve(HeapVector<Member<USBDevice>>(0));
- get_devices_requests_.clear();
- for (ScriptPromiseResolver* resolver : get_permission_requests_) {
+ // Move the set to a local variable to prevent script execution in Reject()
+ // from invalidating the iterator used by the loop.
+ HeapHashSet<Member<ScriptPromiseResolver>> get_permission_requests;
+ get_permission_requests.swap(get_permission_requests_);
+ for (auto& resolver : get_permission_requests) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotFoundError, kNoDeviceSelected));
}
- get_permission_requests_.clear();
}
void USB::AddedEventListener(const AtomicString& event_type,
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
index da7d3003c3a..23856abc9a5 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -1099,11 +1099,15 @@ void USBDevice::AsyncReset(ScriptPromiseResolver* resolver, bool success) {
void USBDevice::OnConnectionError() {
device_.reset();
opened_ = false;
- for (ScriptPromiseResolver* resolver : device_requests_) {
+
+ // Move the set to a local variable to prevent script execution in Reject()
+ // from invalidating the iterator used by the loop.
+ HeapHashSet<Member<ScriptPromiseResolver>> device_requests;
+ device_requests.swap(device_requests_);
+ for (auto& resolver : device_requests) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotFoundError, kDeviceDisconnected));
}
- device_requests_.clear();
}
bool USBDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) {