Changeset 263545 in webkit


Ignore:
Timestamp:
Jun 25, 2020 4:43:38 PM (4 years ago)
Author:
Chris Dumez
Message:

[iOS] Network process is crashing when launching TJMaxx app due to invalid NetworkProcess::DestroySession IPC message
https://bugs.webkit.org/show_bug.cgi?id=213625
<rdar://problem/64737890>

Reviewed by Geoffrey Garen.

The app is calling [WKWebsiteDataStore init] despite the method being marked as unavailable in
WKWebsiteDataStore.h. As a result, they end up with a WKWebsiteDataStore object whose internal
_websiteDataStore is bad because its constructor was never called. When [WKWebsiteDataStore dealloc]
gets called later own, it calls the ~WebsiteDataStore() destructor for _websiteDataStore but its
m_sessionID is 0 because we never called the constructor. This causes us to send a
NetworkProcess::DestroySession IPC with a sessionID that is 0, which is not valid so the
NetworkProcess crashes.

To address the issue, we now provide an implementation of [WKWebsiteDataStore init] which returns nil
behind a linked-on-after check (since this crashes the app). To keep the app working,
[WKWebsiteDataStore init] returns the default data store until rebuilt with the new SDK. Note that
I tried returning a new ephemeral data store instead but this was getting the app in a bad state.

  • UIProcess/API/Cocoa/WKWebsiteDataStore.h:

Mark "new" as unavailable, otherwise [WKWebsiteDataStore new] builds.

  • UIProcess/API/Cocoa/WKWebsiteDataStore.mm:

(-[WKWebsiteDataStore init]):
Return nil with latest SDK, the default data store otherwise.

  • UIProcess/Cocoa/VersionChecks.h:

Add linked-on-after check.

  • UIProcess/WebsiteData/WebsiteDataStore.cpp:

(WebKit::WebsiteDataStore::~WebsiteDataStore):
Add a release assertion to make sure that m_sessionID is always valid when the destructor is called.

Location:
trunk/Source/WebKit
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r263531 r263545  
     12020-06-25  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] Network process is crashing when launching TJMaxx app due to invalid NetworkProcess::DestroySession IPC message
     4        https://bugs.webkit.org/show_bug.cgi?id=213625
     5        <rdar://problem/64737890>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        The app is calling [WKWebsiteDataStore init] despite the method being marked as unavailable in
     10        WKWebsiteDataStore.h. As a result, they end up with a WKWebsiteDataStore object whose internal
     11        _websiteDataStore is bad because its constructor was never called. When [WKWebsiteDataStore dealloc]
     12        gets called later own, it calls the ~WebsiteDataStore() destructor for _websiteDataStore but its
     13        m_sessionID is 0 because we never called the constructor. This causes us to send a
     14        NetworkProcess::DestroySession IPC with a sessionID that is 0, which is not valid so the
     15        NetworkProcess crashes.
     16
     17        To address the issue, we now provide an implementation of [WKWebsiteDataStore init] which returns nil
     18        behind a linked-on-after check (since this crashes the app). To keep the app working,
     19        [WKWebsiteDataStore init] returns the default data store until rebuilt with the new SDK. Note that
     20        I tried returning a new ephemeral data store instead but this was getting the app in a bad state.
     21
     22        * UIProcess/API/Cocoa/WKWebsiteDataStore.h:
     23        Mark "new" as unavailable, otherwise [WKWebsiteDataStore new] builds.
     24
     25        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
     26        (-[WKWebsiteDataStore init]):
     27        Return nil with latest SDK, the default data store otherwise.
     28
     29        * UIProcess/Cocoa/VersionChecks.h:
     30        Add linked-on-after check.
     31
     32        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     33        (WebKit::WebsiteDataStore::~WebsiteDataStore):
     34        Add a release assertion to make sure that m_sessionID is always valid when the destructor is called.
     35
    1362020-06-25  Daniel Bates  <dabates@apple.com>
    237
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.h

    r243376 r263545  
    4848+ (WKWebsiteDataStore *)nonPersistentDataStore;
    4949
     50- (instancetype)new NS_UNAVAILABLE;
    5051- (instancetype)init NS_UNAVAILABLE;
    5152
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm

    r261038 r263545  
    3131#import "CompletionHandlerCallChecker.h"
    3232#import "ShouldGrandfatherStatistics.h"
     33#import "VersionChecks.h"
    3334#import "WKHTTPCookieStoreInternal.h"
    3435#import "WKNSArray.h"
     
    116117}
    117118
     119- (instancetype)init
     120{
     121    // This is a workaround for apps that were managing to call [WKWebsiteDataStore init].
     122    // FIXME: We should eventually drop this and always return nil.
     123    if (!WebKit::linkedOnOrAfter(WebKit::SDKVersion::FirstWithWKWebsiteDataStoreInitReturningNil)) {
     124        RELEASE_LOG_ERROR(Process, "Application is calling [WKWebsiteDataStore init], which is not supported");
     125        return [WKWebsiteDataStore defaultDataStore];
     126    }
     127    return nil;
     128}
     129
    118130- (void)dealloc
    119131{
  • trunk/Source/WebKit/UIProcess/Cocoa/VersionChecks.h

    r262087 r263545  
    9595    FirstThatSendsNativeMouseEvents = DYLD_IOS_VERSION_13_4,
    9696    FirstWithInitializeWebKit2MainThreadAssertion = DYLD_IOS_VERSION_14_0,
     97    FirstWithWKWebsiteDataStoreInitReturningNil = DYLD_IOS_VERSION_14_0,
    9798#elif PLATFORM(MAC)
    9899    FirstWithNetworkCache = DYLD_MACOSX_VERSION_10_11,
     
    108109    FirstWithSessionCleanupByDefault = DYLD_MACOS_VERSION_FIRST_WITH_SESSION_CLEANUP_BY_DEFAULT,
    109110    FirstWithInitializeWebKit2MainThreadAssertion = DYLD_MACOSX_VERSION_10_16,
     111    FirstWithWKWebsiteDataStoreInitReturningNil = DYLD_MACOSX_VERSION_10_16,
    110112#endif
    111113};
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r263441 r263545  
    125125{
    126126    ASSERT(RunLoop::isMain());
     127    RELEASE_ASSERT(m_sessionID.isValid());
    127128
    128129    platformDestroy();
Note: See TracChangeset for help on using the changeset viewer.