diff --git a/Source/WebKit2/PluginProcess/unix/PluginProcessMainUnix.cpp b/Source/WebKit2/PluginProcess/unix/PluginProcessMainUnix.cpp index 98b1dbf..13ebca6 100644 --- a/Source/WebKit2/PluginProcess/unix/PluginProcessMainUnix.cpp +++ b/Source/WebKit2/PluginProcess/unix/PluginProcessMainUnix.cpp @@ -105,6 +105,14 @@ public: m_parameters.extraInitializationData.add("plugin-path", argv[2]); return ChildProcessMainBase::parseCommandLine(argc, argv); } + + void setAddressSpaceLimit() override + { + // Override with no implementation so that address space will be unlimited. We don't control + // how much AS plugins want to use. E.g. the JVM tries to allocate 34 TB of AS, and the + // plugin process will hang, causing the web process to hang, if it fails to do so. The huge + // AS is probably to implement ASLR, so it should be permitted. + } }; int PluginProcessMainUnix(int argc, char** argv) diff --git a/Source/WebKit2/Shared/unix/ChildProcessMain.cpp b/Source/WebKit2/Shared/unix/ChildProcessMain.cpp index 628be68..a2e5339 100644 --- a/Source/WebKit2/Shared/unix/ChildProcessMain.cpp +++ b/Source/WebKit2/Shared/unix/ChildProcessMain.cpp @@ -26,7 +26,16 @@ #include "config.h" #include "ChildProcessMain.h" +#include #include +#include +#include + +// The address space limit is currently set to 5 GB. In practice, this causes a +// runaway web process to cap out at about 1.4 GB of allocated memory. +#ifndef WEBKIT_CHILD_RLIMIT_AS +#define WEBKIT_CHILD_RLIMIT_AS 5000000000l +#endif namespace WebKit { @@ -40,4 +49,26 @@ bool ChildProcessMainBase::parseCommandLine(int argc, char** argv) return true; } +void ChildProcessMainBase::setAddressSpaceLimit() +{ +#ifdef _LARGEFILE64_SOURCE + rlim64_t addressSpaceLimit = WEBKIT_CHILD_RLIMIT_AS; + char* limitFromEnvironment = getenv("WEBKIT_CHILD_RLIMIT_AS"); + if (limitFromEnvironment) + addressSpaceLimit = atoll(limitFromEnvironment); + + // Prevent runaway web processes from allocating too much address space. + // + // It seems like it would be much better to use RLIMIT_DATA here, which should limit the + // combined size of the initialized data, uninitialized data, and heap segments. But + // RLIMIT_DATA does not apply to memory allocated with mmap(), so it is not really useful. + // For one, we use mmap() extensively in WTF::OSAllocator. For another, glibc's malloc() is + // implemented using mmap(), so RLIMIT_DATA is truely useless. + rlimit64 rlim = {addressSpaceLimit, addressSpaceLimit}; + rlim.rlim_max = rlim.rlim_cur; + if (setrlimit64(RLIMIT_AS, &rlim)) + WTFLogAlways("Failed to set process address space limit: %s", strerror(errno)); +#endif +} + } // namespace WebKit diff --git a/Source/WebKit2/Shared/unix/ChildProcessMain.h b/Source/WebKit2/Shared/unix/ChildProcessMain.h index 7b90294..6c2c6f7 100644 --- a/Source/WebKit2/Shared/unix/ChildProcessMain.h +++ b/Source/WebKit2/Shared/unix/ChildProcessMain.h @@ -37,6 +37,7 @@ public: virtual bool platformInitialize() { return true; } virtual bool parseCommandLine(int argc, char** argv); virtual void platformFinalize() { } + virtual void setAddressSpaceLimit(); const ChildProcessInitializationParameters& initializationParameters() const { return m_parameters; } @@ -49,6 +50,8 @@ int ChildProcessMain(int argc, char** argv) { ChildProcessMainType childMain; + childMain.setAddressSpaceLimit(); + if (!childMain.platformInitialize()) return EXIT_FAILURE; -- 2.4.3