diff options
author | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 20:23:34 +0000 |
---|---|---|
committer | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 20:23:34 +0000 |
commit | 58f54dec2ae3a98283b3defc20bbe3b749fc06a3 (patch) | |
tree | 5cf5916ee1ac6c5b768aef6897f518df475263be /chrome_elf | |
parent | 8e82dd864fd63dd9729f8d75baf69ec9ffb8a8c9 (diff) | |
download | chromium_src-58f54dec2ae3a98283b3defc20bbe3b749fc06a3.zip chromium_src-58f54dec2ae3a98283b3defc20bbe3b749fc06a3.tar.gz chromium_src-58f54dec2ae3a98283b3defc20bbe3b749fc06a3.tar.bz2 |
Add 64-bit support to browser blacklisting
BUG=
Review URL: https://codereview.chromium.org/101203010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249755 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_elf')
-rw-r--r-- | chrome_elf/blacklist/blacklist.cc | 58 | ||||
-rw-r--r-- | chrome_elf/blacklist/blacklist.h | 8 | ||||
-rw-r--r-- | chrome_elf/blacklist/blacklist_interceptions.cc | 10 | ||||
-rw-r--r-- | chrome_elf/blacklist/blacklist_interceptions.h | 10 | ||||
-rw-r--r-- | chrome_elf/blacklist/test/blacklist_test.cc | 3 |
5 files changed, 71 insertions, 18 deletions
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc index 34a498e..bf48435 100644 --- a/chrome_elf/blacklist/blacklist.cc +++ b/chrome_elf/blacklist/blacklist.cc @@ -162,6 +162,13 @@ void RecordSuccessfulThunkSetup(HKEY* key) { namespace blacklist { +#if defined(_WIN64) + // Allocate storage for the pointer to the old NtMapViewOfSectionFunction. +#pragma section(".oldntmap",write,read) + __declspec(allocate(".oldntmap")) + NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL; +#endif + bool LeaveSetupBeacon() { HKEY key = NULL; DWORD disposition = 0; @@ -293,12 +300,6 @@ bool RemoveDllFromBlacklist(const wchar_t* dll_name) { } bool Initialize(bool force) { -#if defined(_WIN64) - // TODO(robertshield): Implement 64-bit support by providing 64-bit - // interceptors. - return false; -#endif - // Check to see that we found the functions we need in ntdll. if (!InitializeInterceptImports()) return false; @@ -347,10 +348,12 @@ bool Initialize(bool force) { } // Create a thunk via the appropriate ServiceResolver instance. - sandbox::ServiceResolverThunk* thunk; + sandbox::ServiceResolverThunk* thunk = NULL; #if defined(_WIN64) - // TODO(robertshield): Use the appropriate thunk for 64-bit support - // when said support is implemented. + // Because Windows 8 and 8.1 have different stubs in 64-bit, + // ServiceResolverThunk can handle all the formats in 64-bit (instead only + // handling 1 like it does in 32-bit versions). + thunk = new sandbox::ServiceResolverThunk(current_process, kRelaxed); #else if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) { if (os_info.version() >= VERSION_WIN8) @@ -379,23 +382,48 @@ bool Initialize(bool force) { thunk->AllowLocalPatches(); - // Get ntdll base, target name, interceptor address, + // We declare this early so it can be used in the 64-bit block below and + // still work on 32-bit build when referenced at the end of the function. + BOOL page_executable = false; + + // Replace the default NtMapViewOfSection with our patched version. +#if defined(_WIN64) NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), reinterpret_cast<void*>(&__ImageBase), "NtMapViewOfSection", NULL, - &blacklist::BlNtMapViewOfSection, + &blacklist::BlNtMapViewOfSection64, thunk_storage, sizeof(sandbox::ThunkData), NULL); + // Keep a pointer to the original code, we don't have enough space to + // add it directly to the call. + g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>( + thunk_storage); + + // Ensure that the pointer to the old function can't be changed. + page_executable = VirtualProtect(&g_nt_map_view_of_section_func, + sizeof(g_nt_map_view_of_section_func), + PAGE_EXECUTE_READ, + &old_protect); +#else + NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName), + reinterpret_cast<void*>(&__ImageBase), + "NtMapViewOfSection", + NULL, + &blacklist::BlNtMapViewOfSection, + thunk_storage, + sizeof(sandbox::ThunkData), + NULL); +#endif delete thunk; // Mark the thunk storage as executable and prevent any future writes to it. - BOOL page_executable = VirtualProtect(&g_thunk_storage, - sizeof(g_thunk_storage), - PAGE_EXECUTE_READ, - &old_protect); + page_executable = page_executable && VirtualProtect(&g_thunk_storage, + sizeof(g_thunk_storage), + PAGE_EXECUTE_READ, + &old_protect); RecordSuccessfulThunkSetup(&key); diff --git a/chrome_elf/blacklist/blacklist.h b/chrome_elf/blacklist/blacklist.h index 7e01354..5237a5c 100644 --- a/chrome_elf/blacklist/blacklist.h +++ b/chrome_elf/blacklist/blacklist.h @@ -5,6 +5,10 @@ #ifndef CHROME_ELF_BLACKLIST_BLACKLIST_H_ #define CHROME_ELF_BLACKLIST_BLACKLIST_H_ +#if defined(_WIN64) +#include "sandbox/win/src/sandbox_nt_types.h" +#endif + namespace blacklist { // Max size of the DLL blacklist. @@ -37,6 +41,10 @@ enum BlacklistState { BLACKLIST_STATE_MAX, }; +#if defined(_WIN64) +extern NtMapViewOfSectionFunction g_nt_map_view_of_section_func; +#endif + // Attempts to leave a beacon in the current user's registry hive. // If the blacklist beacon doesn't say it is enabled or there are any other // errors when creating the beacon, returns false. Otherwise returns true. diff --git a/chrome_elf/blacklist/blacklist_interceptions.cc b/chrome_elf/blacklist/blacklist_interceptions.cc index 2163446..642a8b43 100644 --- a/chrome_elf/blacklist/blacklist_interceptions.cc +++ b/chrome_elf/blacklist/blacklist_interceptions.cc @@ -229,4 +229,14 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection( return ret; } +#if defined(_WIN64) +NTSTATUS WINAPI BlNtMapViewOfSection64( + HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, + SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, + SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { + return BlNtMapViewOfSection(g_nt_map_view_of_section_func, section, process, + base, zero_bits, commit_size, offset, view_size, + inherit, allocation_type, protect); +} +#endif } // namespace blacklist diff --git a/chrome_elf/blacklist/blacklist_interceptions.h b/chrome_elf/blacklist/blacklist_interceptions.h index dfb4495..2ee96b4 100644 --- a/chrome_elf/blacklist/blacklist_interceptions.h +++ b/chrome_elf/blacklist/blacklist_interceptions.h @@ -28,6 +28,16 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection( ULONG allocation_type, ULONG protect); +#if defined(_WIN64) +// Interception of NtMapViewOfSection within the current process. +// It should never be called directly. This function provides the means to +// detect dlls being loaded, so we can patch them if needed. +SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection64( + HANDLE section, HANDLE process, PVOID *base, ULONG_PTR zero_bits, + SIZE_T commit_size, PLARGE_INTEGER offset, PSIZE_T view_size, + SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect); +#endif + } // namespace blacklist #endif // CHROME_ELF_BLACKLIST_BLACKLIST_INTERCEPTIONS_H_ diff --git a/chrome_elf/blacklist/test/blacklist_test.cc b/chrome_elf/blacklist/test/blacklist_test.cc index 07623cd..3a881ad 100644 --- a/chrome_elf/blacklist/test/blacklist_test.cc +++ b/chrome_elf/blacklist/test/blacklist_test.cc @@ -117,8 +117,6 @@ TEST_F(BlacklistTest, AddAndRemoveModules) { } TEST_F(BlacklistTest, LoadBlacklistedLibrary) { -// TODO(robertshield): Add 64-bit support. -#if !defined(_WIN64) base::FilePath current_dir; ASSERT_TRUE(PathService::Get(base::DIR_EXE, ¤t_dir)); @@ -167,5 +165,4 @@ TEST_F(BlacklistTest, LoadBlacklistedLibrary) { EXPECT_TRUE(TestDll_RemoveDllFromBlacklist(uppercase_name.c_str())); } -#endif } |