summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIstiaque Ahmed <lazyboy@chromium.org>2020-03-20 04:42:08 +0000
committerMichal Klocek <michal.klocek@qt.io>2020-04-22 18:10:34 +0000
commit70e5d6e68c2dfa0580cff9efd11a325fad6acf53 (patch)
tree11dcf1b43aed108a0a439e10af0f36f89096e5d9
parent5a7809f25c4e10895eb166a8e9d6301c37aea1cb (diff)
downloadqtwebengine-chromium-70e5d6e68c2dfa0580cff9efd11a325fad6acf53.tar.gz
[Backport] CVE-2020-6454 2/2
Fix couple of ProcessManager UaF issues Worker can legitimately fail to start, this CL clears worker's PendingTasks when that happens. In addition to this, this CL makes ServiceWorkerTaskQueue factory dependent on ProcessManager factory as pending tasks can call out to ProcessManager (courtesy of https://crbug.com/1019161#c16) upon ServiceWorkerTaskQueue's destruction. This CL adds a test for this ensuring a worker's pending_tasks_ is cleared when start worker failure is seen. The test rejects a service worker's install event to trigger the failure. Bug: 1019161 Change-Id: I78e663eef7bc2b590bc44de0d57a54dc0158aec6 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/extensions/browser/service_worker_task_queue.cc23
-rw-r--r--chromium/extensions/browser/service_worker_task_queue.h6
-rw-r--r--chromium/extensions/browser/service_worker_task_queue_factory.cc2
3 files changed, 28 insertions, 3 deletions
diff --git a/chromium/extensions/browser/service_worker_task_queue.cc b/chromium/extensions/browser/service_worker_task_queue.cc
index 087cdb0d519..d5492b22bf0 100644
--- a/chromium/extensions/browser/service_worker_task_queue.cc
+++ b/chromium/extensions/browser/service_worker_task_queue.cc
@@ -224,8 +224,17 @@ void ServiceWorkerTaskQueue::DidStartWorkerFail(
return;
}
- // TODO(lazyboy): Handle failure cases.
- DCHECK(false) << "DidStartWorkerFail: " << context_id.first.extension_id();
+ WorkerState* worker_state = GetWorkerState(context_id);
+ DCHECK(worker_state);
+ if (g_test_observer) {
+ g_test_observer->DidStartWorkerFail(context_id.first.extension_id(),
+ worker_state->pending_tasks_.size());
+ }
+ worker_state->pending_tasks_.clear();
+ // TODO(https://crbug/1062936): Needs more thought: extension would be in
+ // perma-broken state after this as the registration wouldn't be stored if
+ // this happens.
+ LOG(ERROR) << "DidStartWorkerFail " << context_id.first.extension_id();
}
void ServiceWorkerTaskQueue::DidInitializeServiceWorkerContext(
@@ -586,6 +595,16 @@ ServiceWorkerTaskQueue::GetCurrentSequence(
return iter->second;
}
+size_t ServiceWorkerTaskQueue::GetNumPendingTasksForTest(
+ const LazyContextId& lazy_context_id) {
+ auto current_sequence = GetCurrentSequence(lazy_context_id.extension_id());
+ if (!current_sequence)
+ return 0u;
+ const SequencedContextId context_id(lazy_context_id, *current_sequence);
+ WorkerState* worker_state = GetWorkerState(context_id);
+ return worker_state ? worker_state->pending_tasks_.size() : 0u;
+}
+
ServiceWorkerTaskQueue::WorkerState* ServiceWorkerTaskQueue::GetWorkerState(
const SequencedContextId& context_id) {
auto worker_iter = worker_state_map_.find(context_id);
diff --git a/chromium/extensions/browser/service_worker_task_queue.h b/chromium/extensions/browser/service_worker_task_queue.h
index 76b22858cc5..c1a9dd17845 100644
--- a/chromium/extensions/browser/service_worker_task_queue.h
+++ b/chromium/extensions/browser/service_worker_task_queue.h
@@ -135,7 +135,9 @@ class ServiceWorkerTaskQueue : public KeyedService,
// |will_register_service_worker| is true if a Service Worker will be
// registered.
virtual void OnActivateExtension(const ExtensionId& extension_id,
- bool will_register_service_worker) = 0;
+ bool will_register_service_worker) {}
+ virtual void DidStartWorkerFail(const ExtensionId& extension_id,
+ size_t num_pending_tasks) {}
private:
DISALLOW_COPY_AND_ASSIGN(TestObserver);
@@ -143,6 +145,8 @@ class ServiceWorkerTaskQueue : public KeyedService,
static void SetObserverForTest(TestObserver* observer);
+ size_t GetNumPendingTasksForTest(const LazyContextId& lazy_context_id);
+
private:
using SequencedContextId = std::pair<LazyContextId, ActivationSequence>;
diff --git a/chromium/extensions/browser/service_worker_task_queue_factory.cc b/chromium/extensions/browser/service_worker_task_queue_factory.cc
index b62d2c1c1e3..29ff874ef47 100644
--- a/chromium/extensions/browser/service_worker_task_queue_factory.cc
+++ b/chromium/extensions/browser/service_worker_task_queue_factory.cc
@@ -6,6 +6,7 @@
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "extensions/browser/extension_registry_factory.h"
+#include "extensions/browser/process_manager_factory.h"
#include "extensions/browser/service_worker_task_queue.h"
using content::BrowserContext;
@@ -28,6 +29,7 @@ ServiceWorkerTaskQueueFactory::ServiceWorkerTaskQueueFactory()
"ServiceWorkerTaskQueue",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(ExtensionRegistryFactory::GetInstance());
+ DependsOn(ProcessManagerFactory::GetInstance());
}
ServiceWorkerTaskQueueFactory::~ServiceWorkerTaskQueueFactory() {}