Bug 240321

Summary: [Cocoa] ProcessLauncher instance was not released well on the error case.
Product: WebKit Reporter: Basuke Suzuki <basuke>
Component: PlatformAssignee: Basuke Suzuki <basuke>
Status: ASSIGNED    
Severity: Normal CC: basuke, cdumez, kkinnunen, pvollan, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
PoC patch
none
patch basuke: review?, ews-feeder: commit-queue-

Basuke Suzuki
Reported 2022-05-11 16:42:22 PDT
It's very rare case but when xpc is failing to establish the connection to the sub process, the error handler is called after executing xpc_connection_send_message_with_reply(): https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm#L277 and ProcessLauncher is failing its responsibility. At the end the owner of ProcessLauncher is terminated and releases the ownership of ProcessLauncher at the destructor of AuxiliaryProcessProxy. But just before calling xpc_connection_send_message_with_reply(), the process is ref()ed. There's no chance to deref() the instance because the callback of xpc_connection_send_message_with_reply() won't be called if error happens.
Attachments
PoC patch (1.24 KB, patch)
2022-05-11 16:44 PDT, Basuke Suzuki
no flags
patch (1.95 KB, patch)
2022-05-11 17:40 PDT, Basuke Suzuki
basuke: review?
ews-feeder: commit-queue-
Basuke Suzuki
Comment 1 2022-05-11 16:44:32 PDT
Created attachment 459189 [details] PoC patch
Basuke Suzuki
Comment 2 2022-05-11 17:04:30 PDT
I confirmed the dummy destructor was successfully called with this patch.
Basuke Suzuki
Comment 3 2022-05-11 17:40:59 PDT
Basuke Suzuki
Comment 4 2022-05-11 17:42:17 PDT
I'm not confident that this behavior is os version dependent, but it happens on macOS Monterey 12.3.1.
Kimmo Kinnunen
Comment 5 2022-05-12 06:02:20 PDT
(In reply to Basuke Suzuki from comment #2) > I confirmed the dummy destructor was successfully called with this patch. Do you have a suggestion for a good method of making the subprocess startup fail when you confirming this?
Basuke Suzuki
Comment 6 2022-05-12 10:49:59 PDT
(In reply to Kimmo Kinnunen from comment #5) > (In reply to Basuke Suzuki from comment #2) > > I confirmed the dummy destructor was successfully called with this patch. > > Do you have a suggestion for a good method of making the subprocess startup > fail when you confirming this? Check this thread: https://webkit.slack.com/archives/CU64U6FDW/p1652306563278849 Originally I had a build issue with Xcode and that caused the half-baked build artifacts. I didn't notice about that and found this issue. Steps to reproduce this: 1. Delete WebKitBuild 2. Open WebKit.xcworkspace 3. Before doing anything, just change the scheme to MiniBrowser <My Mac> 4. Build and run In my environment (macOS 12.3.1), I see xpc failure and falling into infinite loop of relaunching.
Chris Dumez
Comment 7 2022-05-12 16:38:50 PDT
Comment on attachment 459192 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=459192&action=review > Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm:275 > + processLauncher->deref(); This looks dangerous given this comment below: ``` xpc_connection_send_message_with_reply(m_xpcConnection.get(), bootstrapMessage.get(), dispatch_get_main_queue(), ^(xpc_object_t reply) { // Errors are handled in the event handler. // It is possible for this block to be called after the error event handler, in which case we're no longer // launching and we already took care of cleaning things up. ``` It says that the block below (which calls deref()), may get called after this error event handler block, which now also calls deref(). If that comment is true, then it seems like your patch might result in crashes. The current model of explicit ref / deref seems so fragile. It would be nice to make it less error-prone.
Chris Dumez
Comment 8 2022-05-12 16:40:57 PDT
Would this work? ``` diff --git a/Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm b/Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm index 972de63c1313..cc87c7e5a11b 100644 --- a/Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm +++ b/Source/WebKit/UIProcess/Launcher/cocoa/ProcessLauncherCocoa.mm @@ -38,6 +38,7 @@ #import <spawn.h> #import <sys/param.h> #import <sys/stat.h> +#import <wtf/BlockPtr.h> #import <wtf/MachSendRight.h> #import <wtf/RunLoop.h> #import <wtf/SoftLinking.h> @@ -299,8 +300,7 @@ void ProcessLauncher::launchProcess() return; } - ref(); - xpc_connection_send_message_with_reply(m_xpcConnection.get(), bootstrapMessage.get(), dispatch_get_main_queue(), ^(xpc_object_t reply) { + xpc_connection_send_message_with_reply(m_xpcConnection.get(), bootstrapMessage.get(), dispatch_get_main_queue(), makeBlockPtr([protectedThis = Ref { *this }](xpc_object_t reply) { // Errors are handled in the event handler. // It is possible for this block to be called after the error event handler, in which case we're no longer // launching and we already took care of cleaning things up. @@ -328,9 +328,7 @@ void ProcessLauncher::launchProcess() didFinishLaunchingProcess(processIdentifier, IPC::Connection::Identifier(listeningPort, m_xpcConnection)); m_xpcConnection = nullptr; } - - deref(); - }); + }).get()); } void ProcessLauncher::terminateProcess() ```
Radar WebKit Bug Importer
Comment 9 2022-05-18 16:43:13 PDT
Note You need to log in before you can comment on or make changes to this bug.