Commit 48066af7 authored by ager@chromium.org's avatar ager@chromium.org

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
parent 60659dd1
...@@ -154,7 +154,7 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm) ...@@ -154,7 +154,7 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm)
safe_int32_mode_enabled_(true), safe_int32_mode_enabled_(true),
function_return_is_shadowed_(false), function_return_is_shadowed_(false),
in_spilled_code_(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) {
} }
......
...@@ -865,8 +865,9 @@ void* OS::Allocate(const size_t requested, ...@@ -865,8 +865,9 @@ void* OS::Allocate(const size_t requested,
// For exectutable pages try and randomize the allocation address // For exectutable pages try and randomize the allocation address
if (prot == PAGE_EXECUTE_READWRITE && msize >= Page::kPageSize) { if (prot == PAGE_EXECUTE_READWRITE && msize >= Page::kPageSize) {
address = (V8::Random() << kPageSizeBits) | kAllocationRandomAddressMin; address = (V8::RandomPrivate() << kPageSizeBits)
address &= kAllocationRandomAddressMax; | kAllocationRandomAddressMin;
address &= kAllocationRandomAddressMax;
} }
LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address), LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
......
...@@ -177,22 +177,41 @@ static uint32_t random_seed() { ...@@ -177,22 +177,41 @@ static uint32_t random_seed() {
} }
uint32_t V8::Random() { typedef struct {
// Random number generator using George Marsaglia's MWC algorithm. uint32_t hi;
static uint32_t hi = 0; uint32_t lo;
static uint32_t lo = 0; } 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 // Initialize seed using the system random(). If one of the seeds
// should ever become zero again, or if random() returns zero, we // should ever become zero again, or if random() returns zero, we
// avoid getting stuck with zero bits in hi or lo by re-initializing // avoid getting stuck with zero bits in hi or lo by re-initializing
// them on demand. // them on demand.
if (hi == 0) hi = random_seed(); if (state->hi == 0) state->hi = random_seed();
if (lo == 0) lo = random_seed(); if (state->lo == 0) state->lo = random_seed();
// Mix the bits. // Mix the bits.
hi = 36969 * (hi & 0xFFFF) + (hi >> 16); state->hi = 36969 * (state->hi & 0xFFFF) + (state->hi >> 16);
lo = 18273 * (lo & 0xFFFF) + (lo >> 16); state->lo = 18273 * (state->lo & 0xFFFF) + (state->lo >> 16);
return (hi << 16) + (lo & 0xFFFF); 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);
} }
......
...@@ -94,6 +94,11 @@ class V8 : public AllStatic { ...@@ -94,6 +94,11 @@ class V8 : public AllStatic {
// Random number generation support. Not cryptographically safe. // Random number generation support. Not cryptographically safe.
static uint32_t Random(); 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); static Object* FillHeapNumberWithRandom(Object* heap_number);
// Idle notification directly from the API. // Idle notification directly from the API.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment