Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: ada15a6825207b391c7a11274907fb454ff9826d
https://github.com/WebKit/WebKit/commit/ada15a6825207b391c7a11274907fb454ff9826d
Author: Chris Dumez <[email protected]>
Date: 2026-06-05 (Fri, 05 Jun 2026)
Changed paths:
M
Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm
M Source/WebKit/NetworkProcess/Notifications/WebPushDaemonConnection.cpp
M Source/WebKit/NetworkProcess/Notifications/WebPushDaemonConnection.h
Log Message:
-----------
REGRESSION(314479@main): Crash in
WebPushD::Connection::connectionReceivedEvent() due to xpc_object_t ODR
violation
https://bugs.webkit.org/show_bug.cgi?id=316390
rdar://178728999
Reviewed by Cameron McCormack.
NetworkProcess crashes on arm64e with EXC_ARM_PAC_FAIL on the virtual
dispatch to WebPushD::Connection::connectionReceivedEvent() inside the
xpc_connection_set_event_handler lambda in DaemonConnectionCocoa.mm.
Root cause is an ODR violation on xpc_object_t. <wtf/spi/darwin/XPCSPI.h>
ultimately reaches <os/object.h>, which gates OS_OBJECT_USE_OBJC on
__OBJC__:
- In .mm TUs, OS_OBJECT_USE_OBJC = 1 and xpc_object_t resolves to
OS_xpc_object* (an Objective-C class).
- In .cpp TUs, OS_OBJECT_USE_OBJC = 0 and xpc_object_t resolves to
void*.
Because Daemon::ConnectionToMachService<Traits>::connectionReceivedEvent
takes xpc_object_t in its declaration, and WebPushDaemonConnection.h is
consumed by both a .cpp TU (WebPushDaemonConnection.cpp) and a .mm TU
(DaemonConnectionCocoa.mm), the two TUs disagree on the virtual's type:
.cpp: ...connectionReceivedEventEPv
.mm: ...connectionReceivedEventEPU24objcproto13OS_xpc_object8NSObject
On arm64e, vtable function pointers are PAC-signed at vtable-emission
time with a discriminator derived from the function's mangled name. The
two TUs therefore produce vtables whose slot for connectionReceivedEvent
is signed with different discriminators, while .mm call sites always
expect the ObjC discriminator.
Before 314479@main, WebPushD::Connection had no out-of-line virtual, so
its vtable was emitted linkonce_odr from every TU that needed it; the
linker resolved to the .mm-emitted copy and .mm call sites authenticated
correctly. 314479@main out-of-lined the destructor as a workaround for
rdar://176736350, making the dtor the key function and forcing a single
strong-external vtable emission from WebPushDaemonConnection.cpp -- the
.cpp TU with the wrong (void*) discriminator. Every .mm call site now
PAC-fails on dispatch.
PCM::Connection is not affected: its key function is the out-of-line
newConnectionWasInitialized(), defined on Cocoa in
PrivateClickMeasurementConnectionCocoa.mm. That TU is already an .mm,
so the vtable already emits with the ObjC discriminator.
Fix by gating the destructor declaration on PLATFORM(COCOA) and moving
its definition from WebPushDaemonConnection.cpp to
WebPushDaemonConnectionCocoa.mm. The destructor remains the key
function, so the vtable is now emitted in a .mm TU where xpc_object_t
resolves to OS_xpc_object*, the slot is signed with the ObjC
discriminator, and .mm call sites authenticate cleanly.
ENABLE_WEB_PUSH_NOTIFICATIONS is Cocoa-only (PlatformEnableCocoa.h), so
gating the destructor on PLATFORM(COCOA) is a no-op for non-Cocoa ports.
*
Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm:
(WebKit::WebPushD::Connection::~Connection): Defined here, with a comment
explaining why it must live in a .mm TU.
* Source/WebKit/NetworkProcess/Notifications/WebPushDaemonConnection.cpp:
Removed the destructor definition.
* Source/WebKit/NetworkProcess/Notifications/WebPushDaemonConnection.h:
Gate the destructor declaration on PLATFORM(COCOA).
Canonical link: https://commits.webkit.org/314624@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications