RESOLVED FIXED 179190
[iOS-WK1] Fix thread safety issue in WebSQLiteDatabaseTrackerClient
https://bugs.webkit.org/show_bug.cgi?id=179190
Summary [iOS-WK1] Fix thread safety issue in WebSQLiteDatabaseTrackerClient
Chris Dumez
Reported 2017-11-02 12:24:27 PDT
Fix thread safety issue in WebSQLiteDatabaseTrackerClient on iOS WK1. WebSQLiteDatabaseTrackerClient and its HystererisActivity member are constructed on the UIThread. The HystererisActivity activity also fires on the UIThread, which means that WebSQLiteDatabaseTrackerClient::hysteresisUpdated() gets called on the UIThread. However, the code in WebSQLiteDatabaseTrackerClient::willBeginFirstTransaction() / WebSQLiteDatabaseTrackerClient::didFinishLastTransaction() uses callOnMainThread() before calling methods on the HysteresisActivity. callOnMainThread() dispatches to the WebThread on WK1 iOS, which would lead to crashes when calling methods of the HystererisActivity object: *** -[CFRunLoopTimer respondsToSelector:]: message sent to deallocated instance 0x1c0b6a500
Attachments
Patch (3.42 KB, patch)
2017-11-02 12:27 PDT, Chris Dumez
no flags
Archive of layout-test-results from ews124 for ios-simulator-wk2 (1011.12 KB, application/zip)
2017-11-02 13:45 PDT, Build Bot
no flags
Patch (3.32 KB, patch)
2017-11-03 16:40 PDT, Chris Dumez
no flags
Chris Dumez
Comment 1 2017-11-02 12:27:46 PDT
Chris Dumez
Comment 2 2017-11-02 12:36:35 PDT
Build Bot
Comment 3 2017-11-02 13:45:12 PDT
Comment on attachment 325746 [details] Patch Attachment 325746 [details] did not pass ios-sim-ews (ios-simulator-wk2): Output: http://webkit-queues.webkit.org/results/5079376 New failing tests: imported/w3c/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html
Build Bot
Comment 4 2017-11-02 13:45:13 PDT
Created attachment 325762 [details] Archive of layout-test-results from ews124 for ios-simulator-wk2 The attached test failures were seen while running run-webkit-tests on the ios-sim-ews. Bot: ews124 Port: ios-simulator-wk2 Platform: Mac OS X 10.12.6
David Kilzer (:ddkilzer)
Comment 5 2017-11-02 19:44:54 PDT
Comment on attachment 325746 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=325746&action=review r=me if iOS Simulator layout test failure was not caused by this change. > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:55 > + ASSERT([NSThread isMainThread]); Optionally (to avoid Objective-C overhead): ASSERT(ptrhread_main_np()); Not a blocker to land the patch. Change at your discretion. > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:65 > + dispatch_async(dispatch_get_main_queue(), [this] { > + ASSERT([NSThread isMainThread]); This assertion seems redundant; if dispatch_async(dispatch_get_main_queue(), ...) doesn't work, we have bigger problems. :) > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:73 > + dispatch_async(dispatch_get_main_queue(), [this] { > + ASSERT([NSThread isMainThread]); Ditto. > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:80 > + ASSERT([NSThread isMainThread]); Optionally (to avoid Objective-C overhead): ASSERT(ptrhread_main_np());
Chris Dumez
Comment 6 2017-11-03 16:40:15 PDT
Simon Fraser (smfr)
Comment 7 2017-11-03 16:49:29 PDT
Comment on attachment 325988 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=325988&action=review > Source/WebCore/ChangeLog:15 > + would lead to crashes when calling methods of the HystererisActivity object: > + *** -[CFRunLoopTimer respondsToSelector:]: message sent to deallocated instance 0x1c0b6a500 y tho? > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:65 > + dispatch_async(dispatch_get_main_queue(), [this] { > m_hysteresis.start(); Don't you need to WebThreadLock here? > Source/WebCore/platform/ios/WebSQLiteDatabaseTrackerClient.mm:71 > + dispatch_async(dispatch_get_main_queue(), [this] { Don't you need to WebThreadLock here?
Simon Fraser (smfr)
Comment 8 2017-11-03 16:56:56 PDT
Seems like Dave and I are giving conflicting advice. My concern is that it's hard to guarantee that the chain of callbacks from, say, HysteresisActivity::stop() never touch WebCore code.
Chris Dumez
Comment 9 2017-11-03 18:31:10 PDT
(In reply to Simon Fraser (smfr) from comment #8) > Seems like Dave and I are giving conflicting advice. > > My concern is that it's hard to guarantee that the chain of callbacks from, > say, HysteresisActivity::stop() never touch WebCore code. HysteresisActivity is merely a wrapper around a RunLoop::Timer. It does not touch WebCore code.
Chris Dumez
Comment 10 2017-11-03 18:37:21 PDT
(In reply to Simon Fraser (smfr) from comment #7) > Comment on attachment 325988 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=325988&action=review > > > Source/WebCore/ChangeLog:15 > > + would lead to crashes when calling methods of the HystererisActivity object: > > + *** -[CFRunLoopTimer respondsToSelector:]: message sent to deallocated instance 0x1c0b6a500 > > y tho? Here the HysteresisActivity fires (on the UI thread), it calls RunLoop::Timer::stop(): void RunLoop::TimerBase::stop() { if (!m_timer) return; CFRunLoopTimerInvalidate(m_timer.get()); m_timer = nullptr; } At the same time, WebSQLiteDatabaseTrackerClient::willBeginFirstTransaction() could dispatch the the WebThread and call m_hysteresis.start() which calls RunLoop::Timer:isActive(): bool RunLoop::TimerBase::isActive() const { return m_timer && CFRunLoopTimerIsValid(m_timer.get()); } So we have 1 thread invalidating and nulling out m_timer and the other thread calling CFRunLoopTimerIsValid() on the same m_timer.
WebKit Commit Bot
Comment 11 2017-11-03 18:58:01 PDT
Comment on attachment 325988 [details] Patch Clearing flags on attachment: 325988 Committed r224452: <https://trac.webkit.org/changeset/224452>
WebKit Commit Bot
Comment 12 2017-11-03 18:58:02 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.