summaryrefslogtreecommitdiffstats
path: root/chrome_elf
diff options
context:
space:
mode:
authorcsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 20:23:34 +0000
committercsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 20:23:34 +0000
commit58f54dec2ae3a98283b3defc20bbe3b749fc06a3 (patch)
tree5cf5916ee1ac6c5b768aef6897f518df475263be /chrome_elf
parent8e82dd864fd63dd9729f8d75baf69ec9ffb8a8c9 (diff)
downloadchromium_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.cc58
-rw-r--r--chrome_elf/blacklist/blacklist.h8
-rw-r--r--chrome_elf/blacklist/blacklist_interceptions.cc10
-rw-r--r--chrome_elf/blacklist/blacklist_interceptions.h10
-rw-r--r--chrome_elf/blacklist/test/blacklist_test.cc3
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, &current_dir));
@@ -167,5 +165,4 @@ TEST_F(BlacklistTest, LoadBlacklistedLibrary) {
EXPECT_TRUE(TestDll_RemoveDllFromBlacklist(uppercase_name.c_str()));
}
-#endif
}