Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 4aaa3c1477e296e67b03e1461479b8caf57c37dd
https://github.com/WebKit/WebKit/commit/4aaa3c1477e296e67b03e1461479b8caf57c37dd
Author: Chris Dumez <[email protected]>
Date: 2026-07-02 (Thu, 02 Jul 2026)
Changed paths:
A LayoutTests/workers/permissions-query-crash-expected.txt
A LayoutTests/workers/permissions-query-crash.html
M Source/WebCore/Modules/permissions/NavigatorPermissions.h
M Source/WebCore/Modules/permissions/Permissions.cpp
M Source/WebCore/Modules/permissions/Permissions.h
M Source/WebCore/Modules/permissions/WorkerNavigatorPermissions.h
Log Message:
-----------
UAF in WebContent due to Cross-thread destruction race of worker
DeferredPromise via Permissions::query() + worker.terminate()
https://bugs.webkit.org/show_bug.cgi?id=312459
rdar://174651133
Reviewed by Ryosuke Niwa.
When Permissions::query() is called in a worker, we would dispatch a lambda
to the main thread, get the information and then try to go back to the
worker thread using ScriptExecutionContext::postTaskTo() in order to
call the promise with the result. However, in case of worker termination,
ScriptExecutionContext::postTaskTo() would fail and the lambda would get
destroyed on the main thread, without getting called. This would lead to
a security bug because the lambda was capturing the promise object which
is a worker object and thus should not get destroyed on the main thread.
To address the issue, we now store the promise in a HashMap on the
Permissions object. We then capture a promise identifier in the lambda
instead of the promise. In the ~Permissions() destructor, if there are
pending promises, we reject them.
I made the following changes also:
1. I used `Ref<DeferredPromise>` type for the promise instead of
`DOMPromiseDeferred<IDLInterface<PermissionStatus>>` so that I could
store the promise in a HashMap.
2. There was a LOT of code duplication in Permissions::query() for the
main thread code path and the worker code path. I merged them so we
now have a single code path for both. This simplifies things a lot.
Test: workers/permissions-query-crash.html
* LayoutTests/workers/permissions-query-crash-expected.txt: Added.
* LayoutTests/workers/permissions-query-crash.html: Added.
* Source/WebCore/Modules/permissions/NavigatorPermissions.h:
* Source/WebCore/Modules/permissions/Permissions.cpp:
(WebCore::determineGeolocationPermissionState):
(WebCore::Permissions::~Permissions):
(WebCore::processPermissionQueryResult):
(WebCore::Permissions::query):
* Source/WebCore/Modules/permissions/Permissions.h:
Originally-landed-as: 305413.686@safari-7624-branch (f7d3c0785bb0).
rdar://180428980
Canonical link: https://commits.webkit.org/316383@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications