← All issues

REGRESSION(314479@main): Crash in WebPushD::Connection::connectionReceivedEvent() due to xpc_object_t ODR violation

ada15a6

// Source/WebKit/NetworkProcess/Notifications/Cocoa/WebPushDaemonConnectionCocoa.mm
+// 이 destructor는 반드시 이 .mm 파일에 정의되어야 합니다 (WebPushDaemonConnection.cpp에는 두면 안 됩니다).
+// pure하지 않고 inline도 아닌 첫 번째 virtual로서 Connection의 key function에 해당하며,
+// vtable은 이와 동일한 translation unit에서 생성됩니다. xpc_object_t는 .mm TU에서는
+// OS_xpc_object*로, .cpp TU에서는 void*로 해석됩니다. .cpp TU에서 vtable을 생성하면
+// 슬롯이 void* discriminator로 서명되어, .mm 호출 지점마다 arm64e PAC 실패가 발생합니다.
+Connection::~Connection() = default;

arm64e는 각 virtual function의 mangled name을 기반으로 PAC discriminator를 산출하고, vtable function pointer에 서명합니다. C 헤더 <os/object.h>__OBJC__ 여부에 따라 OS_OBJECT_USE_OBJC를 제어합니다. 그 결과, .mm TU에서는 xpc_object_t가 ObjC object pointer(OS_xpc_object*)로 해석되어 특정 mangled name을 생성하고, .cpp TU에서는 void*로 해석되어 다른 mangled name이 생성됩니다. C++ vtable 생성은 key function 규칙을 따릅니다. vtable은 key function(pure하지 않고 inline도 아닌 첫 번째 out-of-line virtual)을 정의하는 TU에서 strong external symbol로 단 한 번 방출됩니다.

이 commit은 WebPushD::Connection::~Connection()WebPushDaemonConnection.cpp에서 WebPushDaemonConnectionCocoa.mm으로 이동시켰습니다. destructor가 key function이므로, vtable은 이제 .mm TU에서 방출됩니다. 이에 따라 모든 슬롯이 .mm 호출 지점에서 기대하는 ObjC OS_xpc_object* discriminator로 서명됩니다. 수정 이전에는 vtable이 .cpp에서 방출되어 void* 기반 discriminator가 적용되었고, .mm 호출 지점마다 NetworkProcess에서 EXC_ARM_PAC_FAIL이 발생했습니다.

감지되기 어려운 ODR violation으로 인해 WebPushD::Connection의 vtable이 잘못된 PAC discriminator로 서명되어 arm64e crash를 유발하는 문제를 수정합니다. 동일한 패턴이 Cocoa 연동 WebKit 코드 전반에서 반복될 경우, arm64e PAC 보호가 눈에 띄지 않게 약화될 수 있는 구조적 함정입니다.

🔒

The pattern this fixes may repeat across other Cocoa-facing virtual dispatch paths — a broader audit of vtable key function placement is warranted.

더 확인하려면 구독해 주세요