[iOS] Add assert to catch improper use of WebCore::Timer in UI Process
authorddkilzer@apple.com <ddkilzer@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Jul 2018 10:41:37 +0000 (10:41 +0000)
committerddkilzer@apple.com <ddkilzer@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Jul 2018 10:41:37 +0000 (10:41 +0000)
<https://webkit.org/b/185330>
<rdar://problem/32816079>

Reviewed by Darin Adler.

Source/WebCore:

* platform/RuntimeApplicationChecks.cpp:
(WebCore::s_webKitProcessType): Add. Global to track process
type.
(WebCore::setWebKitProcessType): Implement new function that is
called when initializing Web, Network, and Storage processes.
(WebCore::isInNetworkProcess): Add.
(WebCore::isInStorageProcess): Add.
(WebCore::isInWebProcess): Add.
- Check value in s_webKitProcessType to determine which process
  is currently running.
* platform/RuntimeApplicationChecks.h:
(WebCore::isInNetworkProcess): Add.
(WebCore::isInStorageProcess): Add.
(WebCore::isInWebProcess):
- Make available for all platforms.

* platform/Timer.cpp:
(WebCore::TimerBase::TimerBase): Add assert and os_log_fault.
This catches the unwanted behavior on iOS using isAllowed().
(WebCore::TimerBase::isAllowed): Add implementation.
* platform/Timer.h:
(WebCore::TimerBase::isAllowed): Add declaration.

* platform/cocoa/RuntimeApplicationChecksCocoa.mm:
(WebCore::isInWebProcess): Delete.  Replace with method in
RuntimeApplicationChecks.cpp.

Source/WebKit:

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::NetworkProcess):
* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::StorageProcess):
* WebProcess/WebProcess.cpp:
(WebKit::m_nonVisibleProcessCleanupTimer):
- Call setWebKitProcessType() to se the global for the current
  process.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233461 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/RuntimeApplicationChecks.cpp
Source/WebCore/platform/RuntimeApplicationChecks.h
Source/WebCore/platform/Timer.cpp
Source/WebCore/platform/Timer.h
Source/WebCore/platform/cocoa/RuntimeApplicationChecksCocoa.mm
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/StorageProcess/StorageProcess.cpp
Source/WebKit/WebProcess/WebProcess.cpp

index adb97ec..44aef0c 100644 (file)
@@ -1,3 +1,38 @@
+2018-07-03  David Kilzer  <ddkilzer@apple.com>
+
+        [iOS] Add assert to catch improper use of WebCore::Timer in UI Process
+        <https://webkit.org/b/185330>
+        <rdar://problem/32816079>
+
+        Reviewed by Darin Adler.
+
+        * platform/RuntimeApplicationChecks.cpp:
+        (WebCore::s_webKitProcessType): Add. Global to track process
+        type.
+        (WebCore::setWebKitProcessType): Implement new function that is
+        called when initializing Web, Network, and Storage processes.
+        (WebCore::isInNetworkProcess): Add.
+        (WebCore::isInStorageProcess): Add.
+        (WebCore::isInWebProcess): Add.
+        - Check value in s_webKitProcessType to determine which process
+          is currently running.
+        * platform/RuntimeApplicationChecks.h:
+        (WebCore::isInNetworkProcess): Add.
+        (WebCore::isInStorageProcess): Add.
+        (WebCore::isInWebProcess):
+        - Make available for all platforms.
+
+        * platform/Timer.cpp:
+        (WebCore::TimerBase::TimerBase): Add assert and os_log_fault.
+        This catches the unwanted behavior on iOS using isAllowed().
+        (WebCore::TimerBase::isAllowed): Add implementation.
+        * platform/Timer.h:
+        (WebCore::TimerBase::isAllowed): Add declaration.
+
+        * platform/cocoa/RuntimeApplicationChecksCocoa.mm:
+        (WebCore::isInWebProcess): Delete.  Replace with method in
+        RuntimeApplicationChecks.cpp.
+
 2018-07-02  Antti Koivisto  <antti@apple.com>
 
         Tighter limit for canvas memory use on iOS
index 2fe42a9..52432d6 100644 (file)
@@ -46,6 +46,30 @@ static std::optional<int>& presentingApplicationPIDOverride()
     return pid;
 }
 
+#if !PLATFORM(WIN)
+static WebKitProcessType s_webKitProcessType { WebKitProcessType::UIProcess };
+
+void setWebKitProcessType(WebKitProcessType type)
+{
+    s_webKitProcessType = type;
+}
+
+bool isInNetworkProcess()
+{
+    return s_webKitProcessType == WebKitProcessType::NetworkProcess;
+}
+
+bool isInStorageProcess()
+{
+    return s_webKitProcessType == WebKitProcessType::StorageProcess;
+}
+
+bool isInWebProcess()
+{
+    return s_webKitProcessType == WebKitProcessType::WebProcess;
+}
+#endif
+
 int presentingApplicationPID()
 {
     const auto& pid = presentingApplicationPIDOverride();
index 94e28f8..ed34ad5 100644 (file)
@@ -33,15 +33,19 @@ WEBCORE_EXPORT void setPresentingApplicationPID(int);
 WEBCORE_EXPORT int presentingApplicationPID();
 
 #if PLATFORM(WIN)
+inline bool isInNetworkProcess() { return false; }
+inline bool isInStorageProcess() { return false; }
 inline bool isInWebProcess() { return false; }
-#elif !PLATFORM(COCOA)
-inline bool isInWebProcess() { return true; }
+#else
+enum class WebKitProcessType { UIProcess = 0, NetworkProcess, StorageProcess, WebProcess };
+WEBCORE_EXPORT void setWebKitProcessType(WebKitProcessType);
+bool isInNetworkProcess();
+bool isInStorageProcess();
+bool isInWebProcess();
 #endif
 
 #if PLATFORM(COCOA)
 
-bool isInWebProcess();
-
 WEBCORE_EXPORT void setApplicationBundleIdentifier(const String&);
 String applicationBundleIdentifier();
 
index 43a5920..73c207b 100644 (file)
 #include "config.h"
 #include "Timer.h"
 
+#include "Logging.h"
+#include "RuntimeApplicationChecks.h"
 #include "SharedTimer.h"
 #include "ThreadGlobalData.h"
 #include "ThreadTimers.h"
 #include <limits.h>
 #include <limits>
 #include <math.h>
+#include <wtf/Compiler.h>
 #include <wtf/MainThread.h>
 #include <wtf/Vector.h>
 
+#if USE(WEB_THREAD)
+#include "WebCoreThread.h"
+#endif
+
 namespace WebCore {
 
 class TimerHeapReference;
@@ -186,6 +193,14 @@ inline bool TimerHeapLessThanFunction::operator()(const TimerBase* a, const Time
 
 TimerBase::TimerBase()
 {
+#if PLATFORM(IOS)
+    if (UNLIKELY(!isAllowed())) {
+#define WEBCORE_TIMERBASE_ASSERTION_MESSAGE "WebCore::Timer should not be used in UI Process."
+        ASSERT_WITH_MESSAGE(false, WEBCORE_TIMERBASE_ASSERTION_MESSAGE);
+        RELEASE_LOG_FAULT(Threading, WEBCORE_TIMERBASE_ASSERTION_MESSAGE);
+#undef WEBCORE_TIMERBASE_ASSERTION_MESSAGE
+    }
+#endif
 }
 
 TimerBase::~TimerBase()
@@ -242,6 +257,23 @@ inline void TimerBase::checkConsistency() const
         checkHeapIndex();
 }
 
+bool TimerBase::isAllowed()
+{
+#if PLATFORM(IOS)
+    if (isInWebProcess() || isInNetworkProcess() || isInStorageProcess())
+        return true;
+
+#if USE(WEB_THREAD)
+    if (WebThreadIsEnabled() && (WebThreadIsCurrent() || WebThreadIsLocked()))
+        return true;
+#endif
+
+    return false;
+#else
+    return true;
+#endif
+}
+
 void TimerBase::heapDecreaseKey()
 {
     ASSERT(static_cast<bool>(m_nextFireTime));
index 524d486..b38bb0e 100644 (file)
@@ -78,6 +78,8 @@ private:
     void checkConsistency() const;
     void checkHeapIndex() const;
 
+    static bool isAllowed();
+
     void setNextFireTime(MonotonicTime);
 
     bool inHeap() const { return m_heapIndex != -1; }
index 571454e..a5822c4 100644 (file)
@@ -65,14 +65,6 @@ void setApplicationBundleIdentifier(const String& bundleIdentifier)
     applicationBundleIdentifierOverride() = bundleIdentifier;
 }
 
-bool isInWebProcess()
-{
-    static bool mainBundleIsWebProcess = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.WebKit.WebContent.Development"]
-        || [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.WebKit.WebContent"]
-        || [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.WebProcess"];
-    return mainBundleIsWebProcess;
-}
-
 static bool applicationBundleIsEqualTo(const String& bundleIdentifierString)
 {
     return applicationBundleIdentifier() == bundleIdentifierString;
index 29e7bcb..98f0a40 100644 (file)
@@ -1,3 +1,20 @@
+2018-07-03  David Kilzer  <ddkilzer@apple.com>
+
+        [iOS] Add assert to catch improper use of WebCore::Timer in UI Process
+        <https://webkit.org/b/185330>
+        <rdar://problem/32816079>
+
+        Reviewed by Darin Adler.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::NetworkProcess):
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::StorageProcess):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::m_nonVisibleProcessCleanupTimer):
+        - Call setWebKitProcessType() to se the global for the current
+          process.
+
 2018-07-03  Frederic Wang  <fred.wang@free.fr>
 
         [iOS] Animations with B├ęzier timing function not suspended on UI process when animation-play-state is set to "paused"
index 67bc9e1..857edb9 100644 (file)
@@ -128,6 +128,8 @@ NetworkProcess::NetworkProcess()
         for (auto& webProcessConnection : webProcessConnections)
             webProcessConnection->setOnLineState(isOnLine);
     });
+
+    WebCore::setWebKitProcessType(WebKitProcessType::NetworkProcess);
 }
 
 NetworkProcess::~NetworkProcess()
index c406635..d14e1c2 100644 (file)
@@ -40,6 +40,7 @@
 #include <WebCore/FileSystem.h>
 #include <WebCore/IDBKeyData.h>
 #include <WebCore/NotImplemented.h>
+#include <WebCore/RuntimeApplicationChecks.h>
 #include <WebCore/SWServerWorker.h>
 #include <WebCore/SecurityOrigin.h>
 #include <WebCore/ServiceWorkerClientIdentifier.h>
@@ -72,6 +73,8 @@ StorageProcess::StorageProcess()
     // Make sure the UTF8Encoding encoding and the text encoding maps have been built on the main thread before a background thread needs it.
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=135365 - Need a more explicit way of doing this besides accessing the UTF8Encoding.
     UTF8Encoding();
+
+    WebCore::setWebKitProcessType(WebKitProcessType::StorageProcess);
 }
 
 StorageProcess::~StorageProcess()
index 0066f11..3e26636 100644 (file)
@@ -209,6 +209,8 @@ WebProcess::WebProcess()
     });
     
     Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
+
+    WebCore::setWebKitProcessType(WebKitProcessType::WebProcess);
 }
 
 WebProcess::~WebProcess()