Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: f83706791bcf631b6ec28bec42a1d58101042334
https://github.com/WebKit/WebKit/commit/f83706791bcf631b6ec28bec42a1d58101042334
Author: Chris Dumez <[email protected]>
Date: 2026-09-17 (Thu, 17 Sep 2026)
Changed paths:
M Source/WTF/wtf/text/CString.h
M Source/WebKit/Platform/cocoa/WebPrivacyHelpers.mm
Log Message:
-----------
Crash under configureForAdvancedPrivacyProtections() due to thread safety
issue
https://bugs.webkit.org/show_bug.cgi?id=319652
rdar://181649240
Reviewed by David Kilzer.
setTrackerLookupCallback()'s callback runs on a background (resolver) thread
and looks up owner/host strings in TrackerAddressLookupInfo and
TrackerDomainLookupInfo. These lists are populated and refreshed on the
WebPrivacy thread, yet were accessed with no synchronization, so the callback
could read them while they were being mutated on another thread. On top of the
missing lock, the callback handed the networking stack raw `const char*`s
pointing directly into the lists; those would dangle as soon as the lists were
cleared and rebuilt, and the domain lookup returned its result by value, so the
pointer dangled the moment the temporary was destroyed.
Address the issue as follows:
- Introduce a single lock, shared by both lookup tables, guarding their
population, refresh, and lookups. The locking is encapsulated so a raw pointer
into the lists can never outlive the lock: find() takes the lock internally
and invokes a NOESCAPE callback with the matched entry, returning whether a
match was found, while contains() answers existence-only queries. The
raw-pointer search (matchingInfo) and the lock itself are private to this
file.
- Add UTF8CString::isolatedCopy(), returning a copy backed by its own
CStringBuffer. Since CStringBuffer is not ThreadSafeRefCounted, this is the
safe way to hand a CString's contents to another thread without sharing (and
racing) the buffer's non-atomic refcount.
- The callback copies the matched owner/host into per-thread CStrings via
isolatedCopy() and hands out pointers into those, so nothing it returns to the
networking stack is tied to the refreshable lists.
* Source/WTF/wtf/text/CString.h:
(WTF::CStringWithEncoding::isolatedCopy):
* Source/WebKit/Platform/cocoa/WebPrivacyHelpers.mm:
(WebKit::trackerLookupLock):
(WebKit::TrackerAddressLookupInfo::find):
(WebKit::TrackerAddressLookupInfo::contains):
(WebKit::TrackerAddressLookupInfo::matchingInfo):
(WebKit::TrackerAddressLookupInfo::containsAddress):
(WebKit::TrackerDomainLookupInfo::populateIfNeeded):
(WebKit::TrackerDomainLookupInfo::find):
(WebKit::TrackerDomainLookupInfo::contains):
(WebKit::TrackerDomainLookupInfo::matchingInfo):
(WebKit::configureForAdvancedPrivacyProtections):
(WebKit::isKnownTrackerAddressOrDomain):
(WebKit::isRequestBlockable):
Originally-landed-as: 316606.77@safari-7625-branch (8cfe4260c1d1).
rdar://187506618
Canonical link: https://commits.webkit.org/321348@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications