Title: [244437] trunk
Revision
244437
Author
bfulg...@apple.com
Date
2019-04-18 14:49:21 -0700 (Thu, 18 Apr 2019)

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

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (244436 => 244437)


--- trunk/Source/WebKit/ChangeLog	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Source/WebKit/ChangeLog	2019-04-18 21:49:21 UTC (rev 244437)
@@ -1,3 +1,33 @@
+2019-04-18  Brent Fulgham  <bfulg...@apple.com>
+
+        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.
+
+        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.
+
 2019-04-18  Zalan Bujtas  <za...@apple.com>
 
         Regression (r244291): Broken API Test AutoLayoutRenderingProgressRelativeOrdering

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h (244436 => 244437)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugIn.h	2019-04-18 21:49:21 UTC (rev 244437)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
 - (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController initializeWithObject:(id)initializationObject;
 - (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController didCreateBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController;
 - (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController willDestroyBrowserContextController:(WKWebProcessPlugInBrowserContextController *)browserContextController;
+- (NSArray *)additionalClassesForParameterCoder;
 @end
 
 WK_CLASS_AVAILABLE(macos(10.10), ios(8.0))

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h (244436 => 244437)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h	2019-04-18 21:49:21 UTC (rev 244437)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -167,6 +167,10 @@
 private:
     explicit InjectedBundle(const WebProcessCreationParameters&);
 
+#if PLATFORM(COCOA)
+    bool decodeBundleParameters(API::Data*);
+#endif
+
     String m_path;
     PlatformBundle m_platformBundle; // This is leaked right now, since we never unload the bundle/module.
 

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm (244436 => 244437)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm	2019-04-18 21:49:21 UTC (rev 244437)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -73,6 +73,29 @@
 }
 #endif
 
+bool InjectedBundle::decodeBundleParameters(API::Data* bundleParameterDataPtr)
+{
+    if (!bundleParameterDataPtr)
+        return true;
+
+    auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(bundleParameterDataPtr->bytes())) length:bundleParameterDataPtr->size() freeWhenDone:NO]);
+    
+    auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
+    
+    NSDictionary *dictionary = nil;
+    @try {
+        dictionary = [unarchiver.get() decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
+        ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
+    } @catch (NSException *exception) {
+        LOG_ERROR("Failed to decode bundle parameters: %@", exception);
+        return false;
+    }
+    
+    ASSERT(!m_bundleParameters || m_bundleParameters.get());
+    m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
+    return true;
+}
+
 bool InjectedBundle::initialize(const WebProcessCreationParameters& parameters, API::Object* initializationUserData)
 {
     if (m_sandboxExtension) {
@@ -120,23 +143,8 @@
         }
     }
 
-    if (parameters.bundleParameterData) {
-        auto bundleParameterData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(parameters.bundleParameterData->bytes())) length:parameters.bundleParameterData->size() freeWhenDone:NO]);
+    bool successfullyDecoded = decodeBundleParameters(parameters.bundleParameterData.get());
 
-        auto unarchiver = secureUnarchiverFromData(bundleParameterData.get());
-
-        NSDictionary *dictionary = nil;
-        @try {
-            dictionary = [unarchiver.get() decodeObjectOfClass:[NSObject class] forKey:@"parameters"];
-            ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
-        } @catch (NSException *exception) {
-            LOG_ERROR("Failed to decode bundle parameters: %@", exception);
-        }
-
-        ASSERT(!m_bundleParameters);
-        m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
-    }
-    
 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     // Swizzle [NSEvent modiferFlags], since it always returns 0 when the WindowServer is blocked.
     Method method = class_getClassMethod([NSEvent class], @selector(modifierFlags));
@@ -149,6 +157,8 @@
     // First check to see if the bundle has a WKBundleInitialize function.
     if (initializeFunction) {
         initializeFunction(toAPI(this), toAPI(initializationUserData));
+        if (!successfullyDecoded)
+            decodeBundleParameters(parameters.bundleParameterData.get());
         return true;
     }
 
@@ -173,6 +183,11 @@
     WKWebProcessPlugInController* plugInController = WebKit::wrapper(*this);
     [plugInController _setPrincipalClassInstance:instance];
 
+    if ([instance respondsToSelector:@selector(additionalClassesForParameterCoder)]) {
+        [plugInController extendClassesForParameterCoder:[instance additionalClassesForParameterCoder]];
+        decodeBundleParameters(parameters.bundleParameterData.get());
+    }
+
     if ([instance respondsToSelector:@selector(webProcessPlugIn:initializeWithObject:)]) {
         RetainPtr<id> objCInitializationUserData;
         if (initializationUserData && initializationUserData->type() == API::Object::Type::ObjCObjectGraph)
@@ -255,7 +270,7 @@
 
     NSDictionary *parameters = nil;
     @try {
-        parameters = [unarchiver decodeObjectOfClass:[NSDictionary class] forKey:@"parameters"];
+        parameters = [unarchiver decodeObjectOfClasses:classesForCoder() forKey:@"parameters"];
     } @catch (NSException *exception) {
         LOG_ERROR("Failed to decode bundle parameter: %@", exception);
     }
@@ -263,6 +278,8 @@
     if (!parameters)
         return;
 
+    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION([parameters isKindOfClass:[NSDictionary class]]);
+
     if (!m_bundleParameters) {
         m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:parameters]);
         return;

Modified: trunk/Tools/ChangeLog (244436 => 244437)


--- trunk/Tools/ChangeLog	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Tools/ChangeLog	2019-04-18 21:49:21 UTC (rev 244437)
@@ -1,3 +1,14 @@
+2019-04-18  Brent Fulgham  <bfulg...@apple.com>
+
+        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.
+
+        * TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm:
+        (-[WebProcessPlugIn additionalClassesForParameterCoder]): Added.
+
 2019-04-18  Zalan Bujtas  <za...@apple.com>
 
         Regression (r244291): Broken API Test AutoLayoutRenderingProgressRelativeOrdering

Modified: trunk/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm (244436 => 244437)


--- trunk/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm	2019-04-18 21:45:41 UTC (rev 244436)
+++ trunk/Tools/TestWebKitAPI/cocoa/WebProcessPlugIn/WebProcessPlugIn.mm	2019-04-18 21:49:21 UTC (rev 244437)
@@ -36,6 +36,11 @@
     RetainPtr<id <WKWebProcessPlugIn>> _testPlugIn;
 }
 
+- (NSArray *)additionalClassesForParameterCoder
+{
+    return @[@"MockContentFilterEnabler"];
+}
+
 - (void)webProcessPlugIn:(WKWebProcessPlugInController *)plugInController initializeWithObject:(id)initializationObject
 {
     NSString *testPlugInClassName = [plugInController.parameters valueForKey:TestWebKitAPI::Util::TestPlugInClassNameParameter];
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to