diff options
author | kochi@google.com <kochi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-23 08:57:54 +0000 |
---|---|---|
committer | kochi@google.com <kochi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-23 08:57:54 +0000 |
commit | 726c1c9a2ba380a63d0ca404933daf8c8cff0c65 (patch) | |
tree | 361c680045bc23b6013e53531679f7f7f98beafe | |
parent | a30dee2e694b7164894b86b680a317964a9f9f16 (diff) | |
download | chromium_src-726c1c9a2ba380a63d0ca404933daf8c8cff0c65.zip chromium_src-726c1c9a2ba380a63d0ca404933daf8c8cff0c65.tar.gz chromium_src-726c1c9a2ba380a63d0ca404933daf8c8cff0c65.tar.bz2 |
Revert 246313 "Use an alternate mechanism for CreateFile calls i..."
This caused reading profile error on Windows8 platform.
> Use an alternate mechanism for CreateFile calls in Chrome
>
> BUG=334379
>
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=245464
>
> Review URL: https://codereview.chromium.org/138593004
TBR=caitkp@chromium.org
Review URL: https://codereview.chromium.org/144333003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246541 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/win/iat_patch_function.cc | 15 | ||||
-rw-r--r-- | build/common.gypi | 7 | ||||
-rw-r--r-- | chrome/chrome_dll.gypi | 12 | ||||
-rw-r--r-- | chrome/chrome_exe.gypi | 1 | ||||
-rw-r--r-- | chrome_elf/chrome_elf.def | 1 | ||||
-rw-r--r-- | chrome_elf/chrome_elf.gyp | 46 | ||||
-rw-r--r-- | chrome_elf/chrome_elf_constants.cc | 13 | ||||
-rw-r--r-- | chrome_elf/chrome_elf_constants.h | 14 | ||||
-rw-r--r-- | chrome_elf/chrome_redirects.def | 8 | ||||
-rw-r--r-- | chrome_elf/create_file/chrome_create_file.cc | 237 | ||||
-rw-r--r-- | chrome_elf/create_file/chrome_create_file.h | 38 | ||||
-rw-r--r-- | chrome_elf/create_file/chrome_create_file_unittest.cc | 327 | ||||
-rw-r--r-- | sandbox/win/src/nt_internals.h | 10 |
13 files changed, 3 insertions, 726 deletions
diff --git a/base/win/iat_patch_function.cc b/base/win/iat_patch_function.cc index 42edb35..a4a8902 100644 --- a/base/win/iat_patch_function.cc +++ b/base/win/iat_patch_function.cc @@ -56,23 +56,11 @@ DWORD ModifyCode(void* old_code, void* new_code, int length) { } // Change the page protection so that we can write. - MEMORY_BASIC_INFORMATION memory_info; DWORD error = NO_ERROR; DWORD old_page_protection = 0; - - if (!::VirtualQuery(old_code, &memory_info, sizeof(memory_info))) { - error = GetLastError(); - return error; - } - - DWORD is_executable = (PAGE_EXECUTE | PAGE_EXECUTE_READ | - PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) & - memory_info.Protect; - if (VirtualProtect(old_code, length, - is_executable ? PAGE_EXECUTE_READWRITE : - PAGE_READWRITE, + PAGE_READWRITE, &old_page_protection)) { // Write the data. @@ -86,6 +74,7 @@ DWORD ModifyCode(void* old_code, void* new_code, int length) { &old_page_protection); } else { error = GetLastError(); + NOTREACHED(); } return error; diff --git a/build/common.gypi b/build/common.gypi index e1bab1e3e..90070a6 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -2469,13 +2469,6 @@ ['enable_ipc_fuzzer==1', { 'defines': ['ENABLE_IPC_FUZZER=1'], }], - ['OS=="win" and component=="shared_library"', { - 'dependencies': [ - # All targets in a component build must depend on chrome_redirects, - # to ensure that certain calls go through it. - '<(DEPTH)/chrome_elf/chrome_elf.gyp:chrome_redirects', - ], - }], ], # conditions for 'target_defaults' 'target_conditions': [ ['enable_wexit_time_destructors==1', { diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 1b1120b..e689c453 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -82,11 +82,6 @@ '../content/content.gyp:content_app_browser', ], 'conditions': [ - ['OS=="win"', { - 'dependencies': [ - '<(DEPTH)/chrome_elf/chrome_elf.gyp:chrome_elf', - ], - }], ['use_aura==1', { 'dependencies': [ '../ui/compositor/compositor.gyp:compositor', @@ -359,13 +354,6 @@ 'app/chrome_main_delegate.cc', 'app/chrome_main_delegate.h', ], - 'conditions': [ - ['OS=="win"', { - 'dependencies': [ - '<(DEPTH)/chrome_elf/chrome_elf.gyp:chrome_elf', - ], - }], - ], }, # target chrome_child_dll ], }], diff --git a/chrome/chrome_exe.gypi b/chrome/chrome_exe.gypi index d51b522..be20bc6 100644 --- a/chrome/chrome_exe.gypi +++ b/chrome/chrome_exe.gypi @@ -514,7 +514,6 @@ '../base/base.gyp:base', '../breakpad/breakpad.gyp:breakpad_handler', '../breakpad/breakpad.gyp:breakpad_sender', - '../chrome_elf/chrome_elf.gyp:chrome_elf', '../components/components.gyp:breakpad_component', '../components/components.gyp:policy', '../chrome_elf/chrome_elf.gyp:chrome_elf', diff --git a/chrome_elf/chrome_elf.def b/chrome_elf/chrome_elf.def index 36a1e45..d7d4c9c 100644 --- a/chrome_elf/chrome_elf.def +++ b/chrome_elf/chrome_elf.def @@ -5,5 +5,4 @@ LIBRARY "chrome_elf.dll" EXPORTS - CreateFileW=chrome_redirects.CreateFileW SignalChromeElf diff --git a/chrome_elf/chrome_elf.gyp b/chrome_elf/chrome_elf.gyp index 98da2d7..d011bbb 100644 --- a/chrome_elf/chrome_elf.gyp +++ b/chrome_elf/chrome_elf.gyp @@ -11,35 +11,6 @@ 'blacklist.gypi', ], 'targets': [ - { - 'target_name': 'chrome_redirects', - 'type': 'shared_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'chrome_redirects.def', - ], - 'dependencies': [ - 'chrome_elf_lib', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'BaseAddress': '0x01c10000', - # Set /SUBSYSTEM:WINDOWS. - 'SubSystem': '2', - }, - }, - 'conditions': [ - ['component=="shared_library"', { - # In component builds, all targets depend on chrome_redirects by - # default. Remove it here to avoid a circular dependency. - 'dependencies!': [ - '../chrome_elf/chrome_elf.gyp:chrome_redirects', - ], - }], - ], - }, { 'target_name': 'chrome_elf', 'type': 'shared_library', @@ -54,12 +25,11 @@ 'dependencies': [ 'blacklist', 'chrome_elf_lib', - 'chrome_redirects', ], 'msvs_settings': { 'VCLinkerTool': { 'BaseAddress': '0x01c20000', - # Set /SUBSYSTEM:WINDOWS. + # Set /SUBSYSTEM:WINDOWS for chrome_elf.dll (for consistency). 'SubSystem': '2', 'AdditionalDependencies!': [ 'user32.lib', @@ -76,7 +46,6 @@ 'type': 'executable', 'sources': [ 'blacklist/test/blacklist_test.cc', - 'create_file/chrome_create_file_unittest.cc', 'elf_imports_unittest.cc', 'ntdll_cache_unittest.cc', ], @@ -117,23 +86,10 @@ '..', ], 'sources': [ - 'chrome_elf_constants.cc', - 'chrome_elf_constants.h', 'chrome_elf_types.h', - 'create_file/chrome_create_file.cc', - 'create_file/chrome_create_file.h', 'ntdll_cache.cc', 'ntdll_cache.h', ], - 'conditions': [ - ['component=="shared_library"', { - # In component builds, all targets depend on chrome_redirects by - # default. Remove it here to avoid a circular dependency. - 'dependencies!': [ - '../chrome_elf/chrome_elf.gyp:chrome_redirects', - ], - }], - ], }, ], } diff --git a/chrome_elf/chrome_elf_constants.cc b/chrome_elf/chrome_elf_constants.cc deleted file mode 100644 index 45229be..0000000 --- a/chrome_elf/chrome_elf_constants.cc +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome_elf/chrome_elf_constants.h" - -const wchar_t kUserDataDirName[] = L"User Data"; - -#if defined(GOOGLE_CHROME_BUILD) -const wchar_t kAppDataDirName[] = L"Google\\Chrome"; -#else -const wchar_t kAppDataDirName[] = L"Chromium"; -#endif diff --git a/chrome_elf/chrome_elf_constants.h b/chrome_elf/chrome_elf_constants.h deleted file mode 100644 index 7b10896..0000000 --- a/chrome_elf/chrome_elf_constants.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// A handful of resource-like constants related to the ChromeELF. - -#ifndef CHROME_ELF_CHROME_ELF_CONSTANTS_H_ -#define CHROME_ELF_CHROME_ELF_CONSTANTS_H_ - -// directory names -extern const wchar_t kAppDataDirName[]; -extern const wchar_t kUserDataDirName[]; - -#endif // CHROME_ELF_CHROME_ELF_CONSTANTS_H_ diff --git a/chrome_elf/chrome_redirects.def b/chrome_elf/chrome_redirects.def deleted file mode 100644 index 30eb718..0000000 --- a/chrome_elf/chrome_redirects.def +++ /dev/null @@ -1,8 +0,0 @@ -; Copyright 2014 The Chromium Authors. All rights reserved. -; Use of this source code is governed by a BSD-style license that can be -; found in the LICENSE file. - -LIBRARY "chrome_redirects.dll" - -EXPORTS - CreateFileW=CreateFileWRedirect diff --git a/chrome_elf/create_file/chrome_create_file.cc b/chrome_elf/create_file/chrome_create_file.cc deleted file mode 100644 index 529e014..0000000 --- a/chrome_elf/create_file/chrome_create_file.cc +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome_elf/create_file/chrome_create_file.h" - -#include <string> - -#include "base/strings/string16.h" -#include "chrome_elf/chrome_elf_constants.h" -#include "chrome_elf/ntdll_cache.h" -#include "sandbox/win/src/nt_internals.h" - -namespace { - -// From ShlObj.h in the Windows SDK. -#define CSIDL_LOCAL_APPDATA 0x001c - -typedef BOOL (WINAPI *PathIsUNCFunction)( - IN LPCWSTR path); - -typedef BOOL (WINAPI *PathAppendFunction)( - IN LPWSTR path, - IN LPCWSTR more); - -typedef BOOL (WINAPI *PathIsPrefixFunction)( - IN LPCWSTR prefix, - IN LPCWSTR path); - -typedef HRESULT (WINAPI *SHGetFolderPathFunction)( - IN HWND hwnd_owner, - IN int folder, - IN HANDLE token, - IN DWORD flags, - OUT LPWSTR path); - -PathIsUNCFunction g_path_is_unc_func; -PathAppendFunction g_path_append_func; -PathIsPrefixFunction g_path_is_prefix_func; -SHGetFolderPathFunction g_get_folder_func; - -// Populates the g_*_func pointers to functions which will be used in -// ShouldBypass(). Chrome_elf cannot have a load-time dependency on shell32 or -// shlwapi as this would induce a load-time dependency on user32.dll. Instead, -// the addresses of the functions we need are retrieved the first time this -// method is called, and cached to avoid subsequent calls to GetProcAddress(). -// It is assumed that the host process will never unload these functions. -// Returns true if all the functions needed are present. -bool PopulateShellFunctions() { - // Early exit if functions have already been populated. - if (g_path_is_unc_func && g_path_append_func && - g_path_is_prefix_func && g_get_folder_func) { - return true; - } - - // Get the addresses of the functions we need and store them for future use. - // These handles are intentionally leaked to ensure that these modules do not - // get unloaded. - HMODULE shell32 = ::LoadLibrary(L"shell32.dll"); - HMODULE shlwapi = ::LoadLibrary(L"shlwapi.dll"); - - if (!shlwapi || !shell32) - return false; - - g_path_is_unc_func = reinterpret_cast<PathIsUNCFunction>( - ::GetProcAddress(shlwapi, "PathIsUNCW")); - g_path_append_func = reinterpret_cast<PathAppendFunction>( - ::GetProcAddress(shlwapi, "PathAppendW")); - g_path_is_prefix_func = reinterpret_cast<PathIsPrefixFunction>( - ::GetProcAddress(shlwapi, "PathIsPrefixW")); - g_get_folder_func = reinterpret_cast<SHGetFolderPathFunction>( - ::GetProcAddress(shell32, "SHGetFolderPathW")); - - return g_path_is_unc_func && g_path_append_func && - g_path_is_prefix_func && g_get_folder_func; -} - -} // namespace - -HANDLE WINAPI CreateFileWRedirect( - LPCWSTR file_name, - DWORD desired_access, - DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, - HANDLE template_file) { - if (ShouldBypass(file_name)) { - return CreateFileNTDLL(file_name, - desired_access, - share_mode, - security_attributes, - creation_disposition, - flags_and_attributes, - template_file); - } - return CreateFile(file_name, - desired_access, - share_mode, - security_attributes, - creation_disposition, - flags_and_attributes, - template_file); - -} - -HANDLE CreateFileNTDLL( - LPCWSTR file_name, - DWORD desired_access, - DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, - HANDLE template_file) { - HANDLE file_handle = INVALID_HANDLE_VALUE; - NTSTATUS result = STATUS_UNSUCCESSFUL; - IO_STATUS_BLOCK io_status_block = {}; - - // Convert from Win32 domain to to NT creation disposition values. - switch (creation_disposition) { - case CREATE_NEW: - creation_disposition = FILE_CREATE; - break; - case CREATE_ALWAYS: - creation_disposition = FILE_OVERWRITE_IF; - break; - case OPEN_EXISTING: - creation_disposition = FILE_OPEN; - break; - case OPEN_ALWAYS: - creation_disposition = FILE_OPEN_IF; - break; - case TRUNCATE_EXISTING: - creation_disposition = FILE_OVERWRITE; - break; - default: - SetLastError(ERROR_INVALID_PARAMETER); - return INVALID_HANDLE_VALUE; - } - - if (!g_ntdll_lookup["NtCreateFile"] || - !g_ntdll_lookup["RtlInitUnicodeString"]) { - return INVALID_HANDLE_VALUE; - } - - NtCreateFileFunction create_file = - reinterpret_cast<NtCreateFileFunction>(g_ntdll_lookup["NtCreateFile"]); - - RtlInitUnicodeStringFunction init_unicode_string = - reinterpret_cast<RtlInitUnicodeStringFunction>( - g_ntdll_lookup["RtlInitUnicodeString"]); - - UNICODE_STRING path_unicode_string; - - // Format the path into an NT path. Arguably this should be done with - // RtlDosPathNameToNtPathName_U, but afaict this is equivalent for - // local paths. Using this with a UNC path name will almost certainly - // break in interesting ways. - base::string16 filename_string(L"\\??\\"); - filename_string += file_name; - - init_unicode_string(&path_unicode_string, filename_string.c_str()); - - OBJECT_ATTRIBUTES path_attributes = {}; - InitializeObjectAttributes(&path_attributes, - &path_unicode_string, - OBJ_CASE_INSENSITIVE, - NULL, // No Root Directory - NULL); // No Security Descriptor - - // Set create_options, desired_access, and flags_and_attributes to match those - // set by kernel32!CreateFile. - ULONG create_options = FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_ARCHIVE; - desired_access |= 0x100080; - flags_and_attributes &= 0x2FFA7; - - result = create_file(&file_handle, - desired_access, - &path_attributes, - &io_status_block, - 0, // Allocation size - flags_and_attributes, - share_mode, - creation_disposition, - create_options, - NULL, - 0); - - if (result != STATUS_SUCCESS) { - if (result == STATUS_OBJECT_NAME_COLLISION && - creation_disposition == FILE_CREATE) { - SetLastError(ERROR_FILE_EXISTS); - } - return INVALID_HANDLE_VALUE; - } - - if (creation_disposition == FILE_OPEN_IF) { - SetLastError(io_status_block.Information == FILE_OPENED ? - ERROR_ALREADY_EXISTS : ERROR_SUCCESS); - } else if (creation_disposition == FILE_OVERWRITE_IF) { - SetLastError(io_status_block.Information == FILE_OVERWRITTEN ? - ERROR_ALREADY_EXISTS : ERROR_SUCCESS); - } else { - SetLastError(ERROR_SUCCESS); - } - - return file_handle; -} - -bool ShouldBypass(LPCWSTR file_name) { - // If the shell functions are not present, forward the call to kernel32. - if (!PopulateShellFunctions()) - return false; - - // Forward all UNC filepaths to kernel32. - if (g_path_is_unc_func(file_name)) - return false; - - wchar_t local_appdata_path[MAX_PATH]; - - // Get the %LOCALAPPDATA% Path and append the location of our UserData - // directory to it. - HRESULT appdata_result = g_get_folder_func( - NULL, CSIDL_LOCAL_APPDATA, NULL, 0, local_appdata_path); - - // If getting the %LOCALAPPDATA% path or appending to it failed, then forward - // the call to kernel32. - if (!SUCCEEDED(appdata_result) || - !g_path_append_func(local_appdata_path, kAppDataDirName) || - !g_path_append_func(local_appdata_path, kUserDataDirName)) { - return false; - } - - // Check if we are trying to access something in the UserData dir. If so, - // then redirect the call to bypass kernel32. - return !!g_path_is_prefix_func(local_appdata_path, file_name); -} diff --git a/chrome_elf/create_file/chrome_create_file.h b/chrome_elf/create_file/chrome_create_file.h deleted file mode 100644 index dac93af..0000000 --- a/chrome_elf/create_file/chrome_create_file.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_ELF_CREATE_FILE_CHROME_CREATE_FILE_H_ -#define CHROME_ELF_CREATE_FILE_CHROME_CREATE_FILE_H_ - -#include <windows.h> - -#include "chrome_elf/chrome_elf_types.h" - -// A CreateFileW replacement that will call NTCreateFile directly when the -// criteria defined in ShouldBypass() are satisfied for |lp_file_name|. -extern "C" HANDLE WINAPI CreateFileWRedirect( - LPCWSTR file_name, - DWORD desired_access, - DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, - HANDLE template_file); - -// Partial reimplementation of kernel32!CreateFile (very partial: only handles -// reading and writing to files in the User Data directory). -HANDLE CreateFileNTDLL( - LPCWSTR file_name, - DWORD desired_access, - DWORD share_mode, - LPSECURITY_ATTRIBUTES security_attributes, - DWORD creation_disposition, - DWORD flags_and_attributes, - HANDLE template_file); - -// Determines whether or not we should use our version of CreateFile, or the -// system version (only uses ours if we're writing to the user data directory). -bool ShouldBypass(LPCWSTR file_name); - -#endif // CHROME_ELF_CREATE_FILE_CHROME_CREATE_FILE_H_ diff --git a/chrome_elf/create_file/chrome_create_file_unittest.cc b/chrome_elf/create_file/chrome_create_file_unittest.cc deleted file mode 100644 index 217d129..0000000 --- a/chrome_elf/create_file/chrome_create_file_unittest.cc +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome_elf/create_file/chrome_create_file.h" - -#include <windows.h> - -#include <bitset> -#include <string> - -#include "base/base_paths_win.h" -#include "base/file_util.h" -#include "base/files/file_path.h" -#include "base/files/scoped_temp_dir.h" -#include "base/path_service.h" -#include "base/threading/platform_thread.h" -#include "base/win/iat_patch_function.h" -#include "base/win/scoped_handle.h" -#include "base/win/windows_version.h" -#include "chrome_elf/chrome_elf_constants.h" -#include "chrome_elf/ntdll_cache.h" -#include "sandbox/win/src/nt_internals.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - - -namespace { - -// Test fixtures ------------------------------------------------------------- - -class ChromeCreateFileTest : public PlatformTest { - protected: - struct NtCreateFileParams { - ACCESS_MASK desired_access; - OBJECT_ATTRIBUTES object_attributes; - PLARGE_INTEGER allocation_size; - ULONG file_attributes; - ULONG share_access; - ULONG create_disposition; - ULONG create_options; - PVOID ea_buffer; - ULONG ea_length; - }; - - enum CallPath { - ELF, - KERNEL - }; - - template<CallPath path> - static NTSTATUS WINAPI FakeNtCreateFile( - PHANDLE file_handle, - ACCESS_MASK desired_access, - POBJECT_ATTRIBUTES object_attributes, - PIO_STATUS_BLOCK io_status_block, - PLARGE_INTEGER allocation_size, - ULONG file_attributes, - ULONG share_access, - ULONG create_disposition, - ULONG create_options, - PVOID ea_buffer, - ULONG ea_length) { - return self_->HandleCreateFileCall(file_handle, - desired_access, - object_attributes, - io_status_block, - allocation_size, - file_attributes, - share_access, - create_disposition, - create_options, - ea_buffer, - ea_length, - path); - } - - virtual void SetUp() OVERRIDE { - original_thread_ = base::PlatformThread::CurrentId(); - InitCache(); - PlatformTest::SetUp(); - - base::FilePath user_data_dir; - PathService::Get(base::DIR_LOCAL_APP_DATA, &user_data_dir); - ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(user_data_dir)); - ASSERT_TRUE(temp_dir2_.CreateUniqueTempDir()); - self_ = this; - } - - void RedirectNtCreateFileCalls() { - old_func_ptr_ = - reinterpret_cast<NtCreateFileFunction>(g_ntdll_lookup["NtCreateFile"]); - - // KernelBase.dll only exists for Win7 and later, prior to that, kernel32 - // imports from ntdll directly. - if (base::win::GetVersion() < base::win::VERSION_WIN7) { - patcher_.Patch(L"kernel32.dll", "ntdll.dll", "NtCreateFile", - reinterpret_cast<void(*)()>(&FakeNtCreateFile<KERNEL>)); - } else { - patcher_.Patch(L"kernelbase.dll", "ntdll.dll", "NtCreateFile", - reinterpret_cast<void(*)()>(&FakeNtCreateFile<KERNEL>)); - } - - g_ntdll_lookup["NtCreateFile"] = reinterpret_cast<void(*)()>( - &ChromeCreateFileTest::FakeNtCreateFile<ELF>); - } - - void ResetNtCreateFileCalls() { - g_ntdll_lookup["NtCreateFile"] = reinterpret_cast<void*>(old_func_ptr_); - patcher_.Unpatch(); - } - - NTSTATUS HandleCreateFileCall(PHANDLE file_handle, - ACCESS_MASK desired_access, - POBJECT_ATTRIBUTES object_attributes, - PIO_STATUS_BLOCK io_status_block, - PLARGE_INTEGER allocation_size, - ULONG file_attributes, - ULONG share_access, - ULONG create_disposition, - ULONG create_options, - PVOID ea_buffer, - ULONG ea_length, - CallPath call_path) { - if (original_thread_ == base::PlatformThread::CurrentId()) { - SetParams(desired_access, - object_attributes, - allocation_size, - file_attributes, - share_access, - create_disposition, - create_options, - ea_buffer, - ea_length, - call_path == ELF ? &elf_params_ : &kernel_params_); - } - - // Forward the call to the real NTCreateFile. - return old_func_ptr_(file_handle, - desired_access, - object_attributes, - io_status_block, - allocation_size, - file_attributes, - share_access, - create_disposition, - create_options, - ea_buffer, - ea_length); - } - - void SetParams(ACCESS_MASK desired_access, - POBJECT_ATTRIBUTES object_attributes, - PLARGE_INTEGER allocation_size, - ULONG file_attributes, - ULONG share_access, - ULONG create_disposition, - ULONG create_options, - PVOID ea_buffer, - ULONG ea_length, - NtCreateFileParams* params) { - params->desired_access = desired_access; - params->object_attributes.Length = object_attributes->Length; - params->object_attributes.ObjectName = object_attributes->ObjectName; - params->object_attributes.RootDirectory = object_attributes->RootDirectory; - params->object_attributes.Attributes = object_attributes->Attributes; - params->object_attributes.SecurityDescriptor = - object_attributes->SecurityDescriptor; - params->object_attributes.SecurityQualityOfService = - object_attributes->SecurityQualityOfService; - params->allocation_size = allocation_size; - params->file_attributes = file_attributes; - params->share_access = share_access; - params->create_disposition = create_disposition; - params->create_options = create_options; - params->ea_buffer = ea_buffer; - params->ea_length = ea_length; - } - - void CheckParams() { - std::bitset<32> elf((int) elf_params_.desired_access); - std::bitset<32> ker((int) kernel_params_.desired_access); - - EXPECT_EQ(kernel_params_.desired_access, elf_params_.desired_access) - << elf << "\n" << ker; - EXPECT_EQ(kernel_params_.object_attributes.Length, - elf_params_.object_attributes.Length); - EXPECT_EQ(kernel_params_.object_attributes.RootDirectory, - elf_params_.object_attributes.RootDirectory); - EXPECT_EQ(kernel_params_.object_attributes.Attributes, - elf_params_.object_attributes.Attributes); - EXPECT_EQ(kernel_params_.object_attributes.SecurityDescriptor, - elf_params_.object_attributes.SecurityDescriptor); - EXPECT_EQ(kernel_params_.allocation_size, elf_params_.allocation_size); - EXPECT_EQ(kernel_params_.file_attributes, elf_params_.file_attributes); - EXPECT_EQ(kernel_params_.share_access, elf_params_.share_access); - EXPECT_EQ(kernel_params_.create_disposition, - elf_params_.create_disposition); - EXPECT_EQ(kernel_params_.create_options, elf_params_.create_options); - EXPECT_EQ(kernel_params_.ea_buffer, elf_params_.ea_buffer); - EXPECT_EQ(kernel_params_.ea_length, elf_params_.ea_length); - } - - void DoWriteCheck(const base::FilePath& path, bool is_system) { - base::win::ScopedHandle file_handle; - const char kTestData[] = "0123456789"; - int buffer_size = sizeof(kTestData) - 1; - DWORD bytes_written; - - if (is_system) { - file_handle.Set(::CreateFileW(path.value().c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)); - } else { - file_handle.Set(CreateFileNTDLL(path.value().c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)); - } - - - EXPECT_FALSE(file_handle == INVALID_HANDLE_VALUE); - ::WriteFile(file_handle, kTestData, buffer_size, &bytes_written, NULL); - EXPECT_EQ(buffer_size, bytes_written); - } - - void DoReadCheck(const base::FilePath& path, bool is_system) { - base::win::ScopedHandle file_handle; - const char kTestData[] = "0123456789"; - int buffer_size = sizeof(kTestData) - 1; - DWORD bytes_read; - char read_buffer[10]; - - if (is_system) { - file_handle.Set(::CreateFileW(path.value().c_str(), - GENERIC_READ, - 0, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)); - } else { - file_handle.Set(CreateFileNTDLL(path.value().c_str(), - GENERIC_READ, - 0, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL)); - } - - EXPECT_FALSE(file_handle == INVALID_HANDLE_VALUE); - ::ReadFile(file_handle, read_buffer, buffer_size, &bytes_read, NULL); - EXPECT_EQ(buffer_size, bytes_read); - EXPECT_EQ(0, memcmp(kTestData, read_buffer, bytes_read)); - } - - static ChromeCreateFileTest* self_; - - NtCreateFileFunction old_func_ptr_; - base::ScopedTempDir temp_dir_; - base::ScopedTempDir temp_dir2_; - base::win::IATPatchFunction patcher_; - NtCreateFileParams kernel_params_; - NtCreateFileParams elf_params_; - base::PlatformThreadId original_thread_; -}; - -ChromeCreateFileTest* ChromeCreateFileTest::self_ = NULL; - -// Tests --------------------------------------------------------------------- - -TEST_F(ChromeCreateFileTest, CheckWriteAndReadParams) { - RedirectNtCreateFileCalls(); - - // Make sure we can write to this file handle when called via the system. - base::FilePath junk_path_1 = temp_dir_.path().Append(L"junk_1.txt"); - base::FilePath junk_path_2 = temp_dir_.path().Append(L"junk_2.txt"); - DoWriteCheck(junk_path_1, true); - DoWriteCheck(junk_path_2, false); - CheckParams(); - - // Make sure we can read from this file handle when called via the system. - DoReadCheck(junk_path_1, true); - DoReadCheck(junk_path_2, false); - CheckParams(); - - ResetNtCreateFileCalls(); -} - -TEST_F(ChromeCreateFileTest, BypassTest) { - std::wstring UNC_filepath_file(L"\\\\.\\some_file.txt"); - - base::FilePath local_path; - PathService::Get(base::DIR_LOCAL_APP_DATA, &local_path); - local_path = local_path.Append(kAppDataDirName).Append( - kUserDataDirName).Append(L"default\\Preferences"); - - base::FilePath desktop_path; - PathService::Get(base::DIR_USER_DESKTOP, &desktop_path); - desktop_path = desktop_path.Append(L"Downloads\\junk.txt"); - - EXPECT_FALSE(ShouldBypass(UNC_filepath_file.c_str())); - EXPECT_FALSE(ShouldBypass(desktop_path.value().c_str())); - EXPECT_TRUE(ShouldBypass(local_path.value().c_str())); -} - -TEST_F(ChromeCreateFileTest, NtCreateFileAddressCheck) { - HMODULE ntdll_handle = ::GetModuleHandle(L"ntdll.dll"); - EXPECT_EQ(::GetProcAddress(ntdll_handle, "NtCreateFile"), - g_ntdll_lookup["NtCreateFile"]); -} - -TEST_F(ChromeCreateFileTest, ReadWriteFromNtDll) { - base::FilePath file_name = temp_dir_.path().Append(L"some_file.txt"); - DoWriteCheck(file_name, false); - DoReadCheck(file_name, false); -} - -} // namespace diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h index 8b22e0e..e0c74ac 100644 --- a/sandbox/win/src/nt_internals.h +++ b/sandbox/win/src/nt_internals.h @@ -25,7 +25,6 @@ typedef LONG NTSTATUS; #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) #define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L) -#define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS)0xC0000035L) #define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS)0xC000007AL) #define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) #define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL) @@ -126,15 +125,6 @@ typedef struct _IO_STATUS_BLOCK { #define FILE_OPEN_NO_RECALL 0x00400000 #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 -// Create/open result values. These are the disposition values returned on the -// io status information. -#define FILE_SUPERSEDED 0x00000000 -#define FILE_OPENED 0x00000001 -#define FILE_CREATED 0x00000002 -#define FILE_OVERWRITTEN 0x00000003 -#define FILE_EXISTS 0x00000004 -#define FILE_DOES_NOT_EXIST 0x00000005 - typedef NTSTATUS (WINAPI *NtCreateFileFunction)( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, |