summaryrefslogtreecommitdiffstats
path: root/content/plugin
diff options
context:
space:
mode:
authorjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 03:54:08 +0000
committerjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 03:54:08 +0000
commit0604c37482f156120792d3f8c4947a788435e7b6 (patch)
treeb4355f09a51b9dd7c4793d1514bc83ba1a4c188a /content/plugin
parent0297bd6de646b5b9504f2d0228607df9d8b1602e (diff)
downloadchromium_src-0604c37482f156120792d3f8c4947a788435e7b6.zip
chromium_src-0604c37482f156120792d3f8c4947a788435e7b6.tar.gz
chromium_src-0604c37482f156120792d3f8c4947a788435e7b6.tar.bz2
Poke a random-sized memory hole in the plugin process.
VirtualAlloc has relatively predictable allocation ranges. So, we compensate by reserving a random number of pages and setting a timer to unreserve them several minutes after startup. BUG=113891 Review URL: https://chromiumcodereview.appspot.com/9447038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123424 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/plugin')
-rw-r--r--content/plugin/plugin_main.cc42
1 files changed, 42 insertions, 0 deletions
diff --git a/content/plugin/plugin_main.cc b/content/plugin/plugin_main.cc
index 4bf2d8f..4f4f402 100644
--- a/content/plugin/plugin_main.cc
+++ b/content/plugin/plugin_main.cc
@@ -12,6 +12,7 @@
#include <dshow.h>
#endif
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/string_util.h"
@@ -76,6 +77,41 @@ int PreloadIMEForFlash() {
return 2;
}
+// VirtualAlloc doesn't randomize well, so we use these calls to poke a
+// random-sized hole in the address space and set an event to later remove it.
+void FreeRandomMemoryHole(void *hole) {
+ ::VirtualFree(hole, 0, MEM_RELEASE);
+}
+
+bool CreateRandomMemoryHole() {
+ static const uint32_t kRandomValueMask = 0xFFF; // 4095
+ static const uint32_t kRandomValueShift = 2;
+ static const uint32_t kMaxWaitSeconds = 22 * 60; // 22 Minutes in seconds.
+ COMPILE_ASSERT((kMaxWaitSeconds > (kRandomValueMask >> kRandomValueShift)),
+ kMaxWaitSeconds_value_too_small);
+
+ uint32_t rand_val;
+ if (rand_s(&rand_val) != S_OK) {
+ DVLOG(ERROR) << "rand_s() failed";
+ }
+
+ rand_val &= kRandomValueMask;
+ // Reserve up to 256mb (randomly selected) of address space.
+ if (void* hole = ::VirtualAlloc(NULL, 65536 * (1 + rand_val),
+ MEM_RESERVE, PAGE_NOACCESS)) {
+ // Set up an event to remove the memory hole. Base the wait time on the
+ // inverse of the allocation size, meaning a bigger hole gets a shorter
+ // wait (ranging from 5-22 minutes).
+ const uint32_t wait = kMaxWaitSeconds - (rand_val >> kRandomValueShift);
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ base::Bind(&FreeRandomMemoryHole, hole),
+ base::TimeDelta::FromSeconds(wait));
+ return true;
+ }
+
+ return false;
+}
+
#endif
// main() routine for running as the plugin process.
@@ -136,6 +172,12 @@ int PluginMain(const content::MainFunctionParams& parameters) {
// start elevated and it will call DelayedLowerToken(0) when it's ready.
if (IsPluginBuiltInFlash(parsed_command_line)) {
DVLOG(1) << "Sandboxing flash";
+
+ // Poke hole in the address space to improve randomization.
+ if (!CreateRandomMemoryHole()) {
+ DVLOG(ERROR) << "Failed to create random memory hole";
+ }
+
if (!PreloadIMEForFlash())
DVLOG(1) << "IME preload failed";