diff options
author | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 03:54:08 +0000 |
---|---|---|
committer | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 03:54:08 +0000 |
commit | 0604c37482f156120792d3f8c4947a788435e7b6 (patch) | |
tree | b4355f09a51b9dd7c4793d1514bc83ba1a4c188a /content/plugin | |
parent | 0297bd6de646b5b9504f2d0228607df9d8b1602e (diff) | |
download | chromium_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.cc | 42 |
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"; |