Changeset 236289 in webkit


Ignore:
Timestamp:
Sep 20, 2018 4:11:19 PM (6 years ago)
Author:
Brent Fulgham
Message:

InjectedBundle parameters often need initialization function called before unarchiving
https://bugs.webkit.org/show_bug.cgi?id=189709
<rdar://problem/44573653>

Reviewed by Chris Dumez.

Handle the case where the InjectedBundle parameters do not successfully decode because they contain
an unexpected class from the embedding program. If this happens, try decoding the bundle parameters
after the bundle initialiation function runs, which gives the embedding program the opportunity to
register additional classes that are safe for serialization.

Create a new 'decodeBundleParameters' method that contains the logic that used to live in 'initialize'.
This new method returns 'true' if the serialization was successful, otherwise it returns false.

Revise 'initialize' to call this new method and check the return value. If it fails, try decoding the
bundle parameters after the bundle's initialization function is called.

  • WebProcess/InjectedBundle/InjectedBundle.h:
  • WebProcess/InjectedBundle/mac/InjectedBundleMac.mm:

(WebKit::InjectedBundle::initialize): Use the new method.
(WebKit::InjectedBundle::decodeBundleParameters): Added.
(WebKit::InjectedBundle::setBundleParameters): Use 'decodeObjectOfClasses' with the more complete
'classesForCoder' method to unarchive the passed bundle parameters, rather than the
NSDictionary-specific method, since InjectedBundles often encode other types of objects, and the
NSDictionary object may itself hold other kinds of objects.

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r236281 r236289  
     12018-09-20  Brent Fulgham  <bfulgham@apple.com>
     2
     3        InjectedBundle parameters often need initialization function called before unarchiving
     4        https://bugs.webkit.org/show_bug.cgi?id=189709
     5        <rdar://problem/44573653>
     6
     7        Reviewed by Chris Dumez.
     8
     9        Handle the case where the InjectedBundle parameters do not successfully decode because they contain
     10        an unexpected class from the embedding program. If this happens, try decoding the bundle parameters
     11        after the bundle initialiation function runs, which gives the embedding program the opportunity to
     12        register additional classes that are safe for serialization.
     13       
     14        Create a new 'decodeBundleParameters' method that contains the logic that used to live in 'initialize'.
     15        This new method returns 'true' if the serialization was successful, otherwise it returns false.
     16
     17        Revise 'initialize' to call this new method and check the return value. If it fails, try decoding the
     18        bundle parameters after the bundle's initialization function is called.
     19
     20        * WebProcess/InjectedBundle/InjectedBundle.h:
     21        * WebProcess/InjectedBundle/mac/InjectedBundleMac.mm:
     22        (WebKit::InjectedBundle::initialize): Use the new method.
     23        (WebKit::InjectedBundle::decodeBundleParameters): Added.
     24        (WebKit::InjectedBundle::setBundleParameters): Use 'decodeObjectOfClasses' with the more complete
     25        'classesForCoder' method to unarchive the passed bundle parameters, rather than the
     26        NSDictionary-specific method, since InjectedBundles often encode other types of objects, and the
     27        NSDictionary object may itself hold other kinds of objects.
     28
    1292018-09-20  Jer Noble  <jer.noble@apple.com>
    230
  • trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h

    r235408 r236289  
    169169    explicit InjectedBundle(const WebProcessCreationParameters&);
    170170
     171#if PLATFORM(COCOA) && WK_API_ENABLED
     172    void decodeBundleParameters(API::Data*);
     173#endif
     174
    171175    String m_path;
    172176    PlatformBundle m_platformBundle; // This is leaked right now, since we never unload the bundle/module.
  • trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm

    r235205 r236289  
    9999    }
    100100
    101 #if WK_API_ENABLED
    102     if (parameters.bundleParameterData) {
    103         auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(parameters.bundleParameterData->bytes())) length:parameters.bundleParameterData->size() freeWhenDone:NO]);
    104 
    105         auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
    106 
    107         NSDictionary *dictionary = nil;
    108         @try {
    109             dictionary = [unarchiver.get() decodeObjectOfClass:[NSObject class] forKey:@"parameters"];
    110             ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
    111         } @catch (NSException *exception) {
    112             LOG_ERROR("Failed to decode bundle parameters: %@", exception);
    113         }
    114 
    115         ASSERT(!m_bundleParameters);
    116         m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
    117     }
    118 #endif
    119    
    120101    if (!initializeFunction)
    121102        initializeFunction = bitwise_cast<WKBundleInitializeFunctionPtr>(CFBundleGetFunctionPointerForName([m_platformBundle _cfBundle], CFSTR("WKBundleInitialize")));
     
    124105    if (initializeFunction) {
    125106        initializeFunction(toAPI(this), toAPI(initializationUserData));
     107#if WK_API_ENABLED
     108        decodeBundleParameters(parameters.bundleParameterData.get());
     109#endif
    126110        return true;
    127111    }
    128112
    129113#if WK_API_ENABLED
     114    decodeBundleParameters(parameters.bundleParameterData.get());
     115
    130116    // Otherwise, look to see if the bundle has a principal class
    131117    Class principalClass = [m_platformBundle principalClass];
     
    206192    return m_classesForCoder.get();
    207193}
     194
     195void InjectedBundle::decodeBundleParameters(API::Data* bundleParameterDataPtr)
     196{
     197    if (!bundleParameterDataPtr)
     198        return;
     199
     200    auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(bundleParameterDataPtr->bytes())) length:bundleParameterDataPtr->size() freeWhenDone:NO]);
     201   
     202    auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
     203   
     204    NSDictionary *dictionary = nil;
     205    @try {
     206        dictionary = [unarchiver.get() decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
     207        ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
     208    } @catch (NSException *exception) {
     209        LOG_ERROR("Failed to decode bundle parameters: %@", exception);
     210        return;
     211    }
     212   
     213    ASSERT(!m_bundleParameters || m_bundleParameters.get());
     214    m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
     215}
     216
    208217#endif
    209218
     
    239248    NSDictionary *parameters = nil;
    240249    @try {
    241         parameters = [unarchiver decodeObjectOfClass:[NSDictionary class] forKey:@"parameters"];
     250        parameters = [unarchiver decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
    242251    } @catch (NSException *exception) {
    243252        LOG_ERROR("Failed to decode bundle parameter: %@", exception);
     
    247256        return;
    248257
     258    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION([parameters isKindOfClass:[NSDictionary class]]);
     259
    249260    if (!m_bundleParameters) {
    250261        m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:parameters]);
Note: See TracChangeset for help on using the changeset viewer.