From 48066af7e0838a2e341f063d8bc6f4aad8f5e725 Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Thu, 18 Nov 2010 08:23:49 +0000 Subject: [PATCH] Landing for Justing Schuh. Split out the random number state between JavaScript and private API I've added v8::RandomPrivate() for internaly used random numbers, and pass the state in as a parameter to a random_base function. I still need to implement strong seeding. I already know how and will be landing that in another patch. BUG=http://code.google.com/p/v8/issues/detail?id=936 TEST=None. Codereview URL: http://codereview.chromium.org/5143004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5845 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/codegen-ia32.cc | 2 +- src/platform-win32.cc | 5 +++-- src/v8.cc | 37 ++++++++++++++++++++++++++++--------- src/v8.h | 5 +++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 9138c34..fb7a138 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -154,7 +154,7 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm) safe_int32_mode_enabled_(true), function_return_is_shadowed_(false), in_spilled_code_(false), - jit_cookie_((FLAG_mask_constants_with_cookie) ? V8::Random() : 0) { + jit_cookie_((FLAG_mask_constants_with_cookie) ? V8::RandomPrivate() : 0) { } diff --git a/src/platform-win32.cc b/src/platform-win32.cc index caea16c..a0ba5e8 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -865,8 +865,9 @@ void* OS::Allocate(const size_t requested, // For exectutable pages try and randomize the allocation address if (prot == PAGE_EXECUTE_READWRITE && msize >= Page::kPageSize) { - address = (V8::Random() << kPageSizeBits) | kAllocationRandomAddressMin; - address &= kAllocationRandomAddressMax; + address = (V8::RandomPrivate() << kPageSizeBits) + | kAllocationRandomAddressMin; + address &= kAllocationRandomAddressMax; } LPVOID mbase = VirtualAlloc(reinterpret_cast(address), diff --git a/src/v8.cc b/src/v8.cc index 43f92b3..c8d719b 100644 --- a/src/v8.cc +++ b/src/v8.cc @@ -177,22 +177,41 @@ static uint32_t random_seed() { } -uint32_t V8::Random() { - // Random number generator using George Marsaglia's MWC algorithm. - static uint32_t hi = 0; - static uint32_t lo = 0; +typedef struct { + uint32_t hi; + uint32_t lo; +} random_state; + +// Random number generator using George Marsaglia's MWC algorithm. +static uint32_t random_base(random_state *state) { // Initialize seed using the system random(). If one of the seeds // should ever become zero again, or if random() returns zero, we // avoid getting stuck with zero bits in hi or lo by re-initializing // them on demand. - if (hi == 0) hi = random_seed(); - if (lo == 0) lo = random_seed(); + if (state->hi == 0) state->hi = random_seed(); + if (state->lo == 0) state->lo = random_seed(); // Mix the bits. - hi = 36969 * (hi & 0xFFFF) + (hi >> 16); - lo = 18273 * (lo & 0xFFFF) + (lo >> 16); - return (hi << 16) + (lo & 0xFFFF); + state->hi = 36969 * (state->hi & 0xFFFF) + (state->hi >> 16); + state->lo = 18273 * (state->lo & 0xFFFF) + (state->lo >> 16); + return (state->hi << 16) + (state->lo & 0xFFFF); +} + + +// Used by JavaScript APIs +uint32_t V8::Random() { + static random_state state = {0, 0}; + return random_base(&state); +} + + +// Used internally by the JIT and memory allocator for security +// purposes. So, we keep a different state to prevent informations +// leaks that could be used in an exploit. +uint32_t V8::RandomPrivate() { + static random_state state = {0, 0}; + return random_base(&state); } diff --git a/src/v8.h b/src/v8.h index 864aa6b..74e98f1 100644 --- a/src/v8.h +++ b/src/v8.h @@ -94,6 +94,11 @@ class V8 : public AllStatic { // Random number generation support. Not cryptographically safe. static uint32_t Random(); + // We use random numbers internally in memory allocation and in the + // compilers for security. In order to prevent information leaks we + // use a separate random state for internal random number + // generation. + static uint32_t RandomPrivate(); static Object* FillHeapNumberWithRandom(Object* heap_number); // Idle notification directly from the API. -- 2.7.4