Bug 159680

Summary: [WK1][iOS] Crash when WebSocket attempts to dispatch a mixed content blocker event
Product: WebKit Reporter: Brent Fulgham <bfulgham>
Component: WebCore Misc.Assignee: Brent Fulgham <bfulgham>
Status: RESOLVED FIXED    
Severity: Normal CC: aestes, andersca, bfulgham, commit-queue, ddkilzer, mcatanzaro, sam, simon.fraser, webkit-bug-importer, zalan
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: iPhone / iPad   
OS: All   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Brent Fulgham
Reported 2016-07-12 10:39:15 PDT
WebSockets on WK1 will sometimes crash with a null pointer exception when attempting to dispatch a mixed content error event.
Attachments
Patch (2.00 KB, patch)
2016-07-12 10:42 PDT, Brent Fulgham
no flags
Patch (6.04 KB, patch)
2016-07-12 16:52 PDT, Brent Fulgham
no flags
Patch (5.88 KB, patch)
2016-07-12 17:56 PDT, Brent Fulgham
no flags
Patch (5.80 KB, patch)
2016-07-12 18:00 PDT, Brent Fulgham
no flags
Patch (5.67 KB, patch)
2016-07-12 18:07 PDT, Brent Fulgham
no flags
Brent Fulgham
Comment 1 2016-07-12 10:39:44 PDT
Brent Fulgham
Comment 2 2016-07-12 10:42:00 PDT
Brent Fulgham
Comment 3 2016-07-12 10:42:36 PDT
I'm working on a suitable LayoutTest, but wanted to get feedback on the use of WebThreadRun.
Anders Carlsson
Comment 4 2016-07-12 10:54:54 PDT
Comment on attachment 283426 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=283426&action=review > Source/WebCore/Modules/websockets/WebSocket.cpp:303 > + WebThreadRun(^{ > + dispatchOrQueueErrorEvent(); > + stop(); > + }); This doesn't protect the socket.
Brent Fulgham
Comment 5 2016-07-12 16:52:16 PDT
Simon Fraser (smfr)
Comment 6 2016-07-12 16:56:57 PDT
Comment on attachment 283470 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=283470&action=review > Source/WebCore/Modules/websockets/WebSocket.cpp:307 > + dispatch_async(dispatch_get_main_queue(), ^{ > + WebThreadRun(^{ > + dispatchOrQueueErrorEvent(); > + stop(); > + deref(); > + }); > + }); WebThreadRun is already async. Why wrap it in a dispatch_async?
Brent Fulgham
Comment 7 2016-07-12 17:40:10 PDT
(In reply to comment #6) > Comment on attachment 283470 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=283470&action=review > > > Source/WebCore/Modules/websockets/WebSocket.cpp:307 > > + dispatch_async(dispatch_get_main_queue(), ^{ > > + WebThreadRun(^{ > > + dispatchOrQueueErrorEvent(); > > + stop(); > > + deref(); > > + }); > > + }); > > WebThreadRun is already async. Why wrap it in a dispatch_async? See the comment on lines 295-299. This WebSocket constructor gets created on the WebThread (at least in iOS/WK1). So calling WebThreadRun immediately begins executing the block, which is not what we want. Instead, we ask the main queue to enqueue the block in the WebThread during the next run loop. It might be cleaner to modify the WebThread API so that I could just enqueue the block in the run queue without executing the code here. E.g., What I really want here is for the block I'm sending to WebThreadRun to be executed on the NEXT run loop. I could do that if I could add it to the runQueue member in WebCore/platform/ios/wak/WebCoreThreadRun.cpp.
Brent Fulgham
Comment 8 2016-07-12 17:40:41 PDT
(In reply to comment #7) > (In reply to comment #6) > > Comment on attachment 283470 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=283470&action=review > > > > > Source/WebCore/Modules/websockets/WebSocket.cpp:307 > > > + dispatch_async(dispatch_get_main_queue(), ^{ > > > + WebThreadRun(^{ > > > + dispatchOrQueueErrorEvent(); > > > + stop(); > > > + deref(); > > > + }); > > > + }); > > > > WebThreadRun is already async. Why wrap it in a dispatch_async? > > See the comment on lines 295-299. > > This WebSocket constructor gets created on the WebThread (at least in > iOS/WK1). So calling WebThreadRun immediately begins executing the block, > which is not what we want. > > Instead, we ask the main queue to enqueue the block in the WebThread during > the next run loop. > > It might be cleaner to modify the WebThread API so that I could just enqueue > the block in the run queue without executing the code here. > > E.g., What I really want here is for the block I'm sending to WebThreadRun > to be executed on the NEXT run loop. I could do that if I could add it to > the runQueue member in WebCore/platform/ios/wak/WebCoreThreadRun.cpp. Andy: Can you recommend a way to do what I want (see my above comment).
Simon Fraser (smfr)
Comment 9 2016-07-12 17:47:45 PDT
Can you just use a zero-delay timer?
Brent Fulgham
Comment 10 2016-07-12 17:56:28 PDT
Andy Estes
Comment 11 2016-07-12 17:57:15 PDT
Comment on attachment 283480 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=283480&action=review > Source/WebCore/Modules/websockets/WebSocket.cpp:304 > +#if USE(WEB_THREAD) > + ASSERT(WebThreadIsCurrent()); > + RunLoop::current().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { > +#else > RunLoop::main().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { > +#endif Won't RunLoop::current() work even int he non-WebThread case?
Brent Fulgham
Comment 12 2016-07-12 18:00:18 PDT
(In reply to comment #11) > Comment on attachment 283480 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=283480&action=review > > > Source/WebCore/Modules/websockets/WebSocket.cpp:304 > > +#if USE(WEB_THREAD) > > + ASSERT(WebThreadIsCurrent()); > > + RunLoop::current().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { > > +#else > > RunLoop::main().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { > > +#endif > > Won't RunLoop::current() work even int he non-WebThread case? It seems to. I'll revise the patch.
Brent Fulgham
Comment 13 2016-07-12 18:00:46 PDT
Andy Estes
Comment 14 2016-07-12 18:04:53 PDT
Comment on attachment 283481 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=283481&action=review > Source/WebCore/Modules/websockets/WebSocket.cpp:68 > +#if USE(WEB_THREAD) > +#include "WebCoreThreadRun.h" > +#endif This shouldn't be needed anymore. > Source/WebCore/Modules/websockets/WebSocket.cpp:299 > - RunLoop::main().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { > + RunLoop::current().dispatch([this, protectedThis = Ref<WebSocket>(*this)]() { An ASSERT(isMainThread()) (which really means is main-or-web thread) would be nice here.
Brent Fulgham
Comment 15 2016-07-12 18:07:34 PDT
Andy Estes
Comment 16 2016-07-12 18:16:42 PDT
Comment on attachment 283483 [details] Patch Wait, couldn't this be called on a worker thread?
Andy Estes
Comment 17 2016-07-12 18:27:43 PDT
(In reply to comment #16) > Comment on attachment 283483 [details] > Patch > > Wait, couldn't this be called on a worker thread? If so, then your solution of dispatching to the main thread then calling WebThreadRun() seems ok to me. You'd only be penalizing iOS WebKit1 with a second dispatch.
Brent Fulgham
Comment 18 2016-07-12 20:05:40 PDT
(In reply to comment #17) > (In reply to comment #16) > > Comment on attachment 283483 [details] > > Patch > > > > Wait, couldn't this be called on a worker thread? > > If so, then your solution of dispatching to the main thread then calling > WebThreadRun() seems ok to me. You'd only be penalizing iOS WebKit1 with a > second dispatch. Yes -- its possible for these WebSockets to be used by workers, so I'll revert back to my original patch. :-)
Brent Fulgham
Comment 19 2016-07-12 20:15:26 PDT
Based on Andy's comments, moving the "dispatch_async(main) + WebThreadRun" version of the patch for approval.
Andy Estes
Comment 20 2016-07-13 10:21:34 PDT
While looking this over I noticed that mixed content checking is bypassed for WebSockets that that don't have Documents. For instance, it's possible to communicate using the ws: protocol from inside a Worker on a secure page. I filed <https://bugs.webkit.org/show_bug.cgi?id=159726> about this.
WebKit Commit Bot
Comment 21 2016-07-13 10:26:15 PDT
Comment on attachment 283470 [details] Patch Clearing flags on attachment: 283470 Committed r203165: <http://trac.webkit.org/changeset/203165>
WebKit Commit Bot
Comment 22 2016-07-13 10:26:20 PDT
All reviewed patches have been landed. Closing bug.
Michael Catanzaro
Comment 23 2016-07-13 14:01:02 PDT
FYI there's probably another crash in this code, bug #149864.
Note You need to log in before you can comment on or make changes to this bug.