Changeset 244299 in webkit


Ignore:
Timestamp:
Apr 15, 2019 3:21:59 PM (5 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 Ryosuke Niwa.

Source/WebKit:

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.

Extend WKWebProcessPlugIn with a method that returns the names of any custom classes that need
to be serialized by the InjectedBundle.

Create a new 'decodeBundleParameters' method that contains the logic that used to live in 'initialize'.
Revise 'initialize' to call this new method.

  • 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.

  • WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h:

(WebKit::WKWebProcessPlugIn::additionalClassesForParameterCoder): Added.

Tools:

  • TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm:

(-[WebProcessPlugIn additionalClassesForParameterCoder]): Added.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r244296 r244299  
     12019-04-15  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 Ryosuke Niwa.
     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        Extend WKWebProcessPlugIn with a method that returns the names of any custom classes that need
     15        to be serialized by the InjectedBundle.
     16       
     17        Create a new 'decodeBundleParameters' method that contains the logic that used to live in 'initialize'.
     18        Revise 'initialize' to call this new method.
     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        * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h:
     29        (WebKit::WKWebProcessPlugIn::additionalClassesForParameterCoder): Added.
     30
    1312019-04-15  Dean Jackson  <dino@apple.com>
    232
  • trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h

    r243376 r244299  
    3838- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController;
    3939- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController willDestroyBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController;
     40- (NSArray *)additionalClassesForParameterCoder;
    4041@end
    4142
  • trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h

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

    r242339 r244299  
    7474#endif
    7575
     76void InjectedBundle::decodeBundleParameters(API::Data* bundleParameterDataPtr)
     77{
     78    if (!bundleParameterDataPtr)
     79        return;
     80
     81    auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(bundleParameterDataPtr->bytes())) length:bundleParameterDataPtr->size() freeWhenDone:NO]);
     82   
     83    auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
     84   
     85    NSDictionary *dictionary = nil;
     86    @try {
     87        dictionary = [unarchiver.get() decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
     88        ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
     89    } @catch (NSException *exception) {
     90        LOG_ERROR("Failed to decode bundle parameters: %@", exception);
     91        return;
     92    }
     93   
     94    ASSERT(!m_bundleParameters || m_bundleParameters.get());
     95    m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
     96}
     97
    7698bool InjectedBundle::initialize(const WebProcessCreationParameters& parameters, API::Object* initializationUserData)
    7799{
     
    121143    }
    122144
    123     if (parameters.bundleParameterData) {
    124         auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(parameters.bundleParameterData->bytes())) length:parameters.bundleParameterData->size() freeWhenDone:NO]);
    125 
    126         auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
    127 
    128         NSDictionary *dictionary = nil;
    129         @try {
    130             dictionary = [unarchiver.get() decodeObjectOfClass:[NSObject class] forKey:@"parameters"];
    131             ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
    132         } @catch (NSException *exception) {
    133             LOG_ERROR("Failed to decode bundle parameters: %@", exception);
    134         }
    135 
    136         ASSERT(!m_bundleParameters);
    137         m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
    138     }
    139    
    140145#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    141146    // Swizzle [NSEvent modiferFlags], since it always returns 0 when the WindowServer is blocked.
     
    150155    if (initializeFunction) {
    151156        initializeFunction(toAPI(this), toAPI(initializationUserData));
     157        decodeBundleParameters(parameters.bundleParameterData.get());
    152158        return true;
    153159    }
     
    173179    WKWebProcessPlugInController* plugInController = WebKit::wrapper(*this);
    174180    [plugInController _setPrincipalClassInstance:instance];
     181
     182    if ([instance respondsToSelector:@selector(additionalClassesForParameterCoder)])
     183        [plugInController extendClassesForParameterCoder:[instance additionalClassesForParameterCoder]];
     184
     185    decodeBundleParameters(parameters.bundleParameterData.get());
    175186
    176187    if ([instance respondsToSelector:@selector(webProcessPlugIn:initializeWithObject:)]) {
     
    256267    NSDictionary *parameters = nil;
    257268    @try {
    258         parameters = [unarchiver decodeObjectOfClass:[NSDictionary class] forKey:@"parameters"];
     269        parameters = [unarchiver decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
    259270    } @catch (NSException *exception) {
    260271        LOG_ERROR("Failed to decode bundle parameter: %@", exception);
     
    264275        return;
    265276
     277    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION([parameters isKindOfClass:[NSDictionary class]]);
     278
    266279    if (!m_bundleParameters) {
    267280        m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:parameters]);
  • trunk/Tools/ChangeLog

    r244289 r244299  
     12019-04-15  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 Ryosuke Niwa.
     8
     9        * TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm:
     10        (-[WebProcessPlugIn additionalClassesForParameterCoder]): Added.
     11
    1122019-04-12  Ryosuke Niwa  <rniwa@webkit.org>
    213
  • trunk/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm

    r242339 r244299  
    3737}
    3838
     39- (NSArray *)additionalClassesForParameterCoder
     40{
     41    return @[@"MockContentFilterEnabler"];
     42}
     43
    3944- (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController initializeWithObject:(id)initializationObject
    4045{
Note: See TracChangeset for help on using the changeset viewer.