diff options
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"; |