diff --git a/patches/chromium/.patches b/patches/chromium/.patches index c603b8f994cff..ccd8798eb4dfa 100644 --- a/patches/chromium/.patches +++ b/patches/chromium/.patches @@ -120,3 +120,4 @@ backport_1090543.patch backport_1081722.patch backport_1073409.patch backport_1074340.patch +cherry-pick-70579363ce7b.patch diff --git a/patches/chromium/cherry-pick-70579363ce7b.patch b/patches/chromium/cherry-pick-70579363ce7b.patch new file mode 100644 index 0000000000000..a5b38fa5d64e8 --- /dev/null +++ b/patches/chromium/cherry-pick-70579363ce7b.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Reilly Grant +Date: Wed, 22 Jul 2020 04:00:16 +0000 +Subject: 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 +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2304538 +Auto-Submit: Reilly Grant +Commit-Queue: James Hollyer +Reviewed-by: James Hollyer +Cr-Original-Commit-Position: refs/heads/master@{#790217} +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2310964 +Reviewed-by: Reilly Grant +Commit-Queue: Reilly Grant +Cr-Commit-Position: refs/branch-heads/4183@{#842} +Cr-Branched-From: 740e9e8a40505392ba5c8e022a8024b3d018ca65-refs/heads/master@{#782793} + +diff --git a/third_party/blink/renderer/modules/webusb/usb.cc b/third_party/blink/renderer/modules/webusb/usb.cc +index cbe336ae6991d42aa7082aa99a95c4a380aa790f..ce38760e569e03bef1f64b14fca1122d7f98b452 100644 +--- a/third_party/blink/renderer/modules/webusb/usb.cc ++++ b/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> get_devices_requests; ++ get_devices_requests.swap(get_devices_requests_); ++ for (auto& resolver : get_devices_requests) + resolver->Resolve(HeapVector>(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> get_permission_requests; ++ get_permission_requests.swap(get_permission_requests_); ++ for (auto& resolver : get_permission_requests) { + resolver->Reject(MakeGarbageCollected( + DOMExceptionCode::kNotFoundError, kNoDeviceSelected)); + } +- get_permission_requests_.clear(); + } + + void USB::AddedEventListener(const AtomicString& event_type, +diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc +index da7d3003c3a38cdf650ec0ab5c131fecd80ee4e5..23856abc9a59770f816c6d18cd12602e6d0dae58 100644 +--- a/third_party/blink/renderer/modules/webusb/usb_device.cc ++++ b/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> device_requests; ++ device_requests.swap(device_requests_); ++ for (auto& resolver : device_requests) { + resolver->Reject(MakeGarbageCollected( + DOMExceptionCode::kNotFoundError, kDeviceDisconnected)); + } +- device_requests_.clear(); + } + + bool USBDevice::MarkRequestComplete(ScriptPromiseResolver* resolver) {