diff options
author | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-25 22:08:37 +0000 |
---|---|---|
committer | jschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-25 22:08:37 +0000 |
commit | b2e600b62f2251f92b45b05db67fd663042fef34 (patch) | |
tree | 20f73ea3d125097060f912b7d6275e7d140aa67f /sandbox | |
parent | 696c93c1136d4de9d3d50124a8e728fbad7d9537 (diff) | |
download | chromium_src-b2e600b62f2251f92b45b05db67fd663042fef34.zip chromium_src-b2e600b62f2251f92b45b05db67fd663042fef34.tar.gz chromium_src-b2e600b62f2251f92b45b05db67fd663042fef34.tar.bz2 |
Add eight more bits of entropy to the sandbox intercept trampoline
Review URL: https://chromiumcodereview.appspot.com/10666018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144031 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/src/interception.cc | 48 | ||||
-rw-r--r-- | sandbox/src/target_process.cc | 4 |
2 files changed, 44 insertions, 8 deletions
diff --git a/sandbox/src/interception.cc b/sandbox/src/interception.cc index a873f4a..a850c6e 100644 --- a/sandbox/src/interception.cc +++ b/sandbox/src/interception.cc @@ -27,6 +27,28 @@ namespace { const char kMapViewOfSectionName[] = "NtMapViewOfSection"; const char kUnmapViewOfSectionName[] = "NtUnmapViewOfSection"; +// Standard allocation granularity and page size for Windows. +const size_t kAllocGranularity = 65536; +const size_t kPageSize = 4096; + +// Find a random offset within 64k and aligned to ceil(log2(size)). +size_t GetGranularAlignedRandomOffset(size_t size) { + CHECK_LE(size, kAllocGranularity); + unsigned int offset; + + do { + rand_s(&offset); + offset &= (kAllocGranularity - 1); + } while (offset > (kAllocGranularity - size)); + + // Find an alignment between 64 and the page size (4096). + size_t align_size = kPageSize; + for (size_t new_size = align_size / 2; new_size >= size; new_size /= 2) { + align_size = new_size; + } + return offset & ~(align_size - 1); +} + } // namespace namespace sandbox { @@ -360,15 +382,29 @@ bool InterceptionManager::PatchNtdll(bool hot_patch_needed) { ADD_NT_INTERCEPTION(NtUnmapViewOfSection, UNMAP_VIEW_OF_SECTION_ID, 12); } + // Reserve a full 64k memory range in the child process. + HANDLE child = child_->Process(); + BYTE* thunk_base = reinterpret_cast<BYTE*>( + ::VirtualAllocEx(child, NULL, kAllocGranularity, + MEM_RESERVE, PAGE_NOACCESS)); + + // Find an aligned, random location within the reserved range. size_t thunk_bytes = interceptions_.size() * sizeof(ThunkData) + sizeof(DllInterceptionData); - - // Allocate memory on the child, without specifying the desired address - HANDLE child = child_->Process(); + size_t thunk_offset = GetGranularAlignedRandomOffset(thunk_bytes); + + // Split the base and offset along page boundaries. + thunk_base += thunk_offset & ~(kPageSize - 1); + thunk_offset &= kPageSize - 1; + + // Make an aligned, padded allocation, and move the pointer to our chunk. + size_t thunk_bytes_padded = (thunk_bytes + kPageSize - 1) & kPageSize; + thunk_base = reinterpret_cast<BYTE*>( + ::VirtualAllocEx(child, thunk_base, thunk_bytes_padded, + MEM_COMMIT, PAGE_EXECUTE_READWRITE)); + CHECK(thunk_base); // If this fails we'd crash anyway on an invalid access. DllInterceptionData* thunks = reinterpret_cast<DllInterceptionData*>( - ::VirtualAllocEx(child, NULL, thunk_bytes, - MEM_COMMIT, - PAGE_EXECUTE_READWRITE)); + thunk_base + thunk_offset); DllInterceptionData dll_data; dll_data.data_bytes = thunk_bytes; diff --git a/sandbox/src/target_process.cc b/sandbox/src/target_process.cc index b8ed1d5..2d3594d 100644 --- a/sandbox/src/target_process.cc +++ b/sandbox/src/target_process.cc @@ -47,8 +47,8 @@ void PoisonLowerAddressRange(HANDLE process) { rand_s(&limit); char* ptr = 0; const size_t kMask64k = 0xFFFF; - // Random range (512k-4.5mb) in 64k steps. - const char* end = ptr + ((((limit % 4096) + 512) * 1024) & ~kMask64k); + // Random range (512k-16.5mb) in 64k steps. + const char* end = ptr + ((((limit % 16384) + 512) * 1024) & ~kMask64k); while (ptr < end) { MEMORY_BASIC_INFORMATION memory_info; if (!::VirtualQueryEx(process, ptr, &memory_info, sizeof(memory_info))) |