diff options
author | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-04 15:15:58 +0000 |
---|---|---|
committer | csharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-04 15:15:58 +0000 |
commit | 6b37624fd9ec1417aeb9523e29daa8460d85a464 (patch) | |
tree | b2065beed08e9b0e2e8556890c4aa8fedd8ed455 /chrome_elf | |
parent | f46e9572a8bbd9e0746bda6097f5b90be94e02f0 (diff) | |
download | chromium_src-6b37624fd9ec1417aeb9523e29daa8460d85a464.zip chromium_src-6b37624fd9ec1417aeb9523e29daa8460d85a464.tar.gz chromium_src-6b37624fd9ec1417aeb9523e29daa8460d85a464.tar.bz2 |
Add New Histogram Stats to see where Blacklist Failures are Occuring
We seem to be seeing more setup failures than expected so add so new
UMA stats to try and narrow down where the problem is occuring.
(This crashes would occur before breakpad is loaded so we don't have
any other way to gather this data for the moment).
NOTRY=True
BUG=329023
Review URL: https://codereview.chromium.org/147143002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@248720 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_elf')
-rw-r--r-- | chrome_elf/blacklist/blacklist.cc | 50 | ||||
-rw-r--r-- | chrome_elf/blacklist/blacklist.h | 6 | ||||
-rw-r--r-- | chrome_elf/blacklist/blacklist_interceptions.cc | 59 |
3 files changed, 111 insertions, 4 deletions
diff --git a/chrome_elf/blacklist/blacklist.cc b/chrome_elf/blacklist/blacklist.cc index f9eb065..34a498e 100644 --- a/chrome_elf/blacklist/blacklist.cc +++ b/chrome_elf/blacklist/blacklist.cc @@ -142,6 +142,22 @@ bool IsNonBrowserProcess() { return (command_line && wcsstr(command_line, L"--type")); } +// Record that the thunk setup completed succesfully and close the registry +// key handle since it is no longer needed. +void RecordSuccessfulThunkSetup(HKEY* key) { + if (key != NULL) { + DWORD blacklist_state = blacklist::BLACKLIST_SETUP_RUNNING; + ::RegSetValueEx(*key, + blacklist::kBeaconState, + 0, + REG_DWORD, + reinterpret_cast<LPBYTE>(&blacklist_state), + sizeof(blacklist_state)); + ::RegCloseKey(*key); + key = NULL; + } +} + } // namespace namespace blacklist { @@ -238,7 +254,7 @@ bool ResetBeacon() { int BlacklistSize() { int size = -1; - while(blacklist::g_troublesome_dlls[++size] != NULL); + while (blacklist::g_troublesome_dlls[++size] != NULL) {} return size; } @@ -248,7 +264,7 @@ bool AddDllToBlacklist(const wchar_t* dll_name) { // We need to leave one space at the end for the null pointer. if (blacklist_size + 1 >= kTroublesomeDllsMaxCount) return false; - for (int i=0; i < blacklist_size; ++i) { + for (int i = 0; i < blacklist_size; ++i) { if (!_wcsicmp(g_troublesome_dlls[i], dll_name)) return true; } @@ -306,6 +322,30 @@ bool Initialize(bool force) { // Tells the resolver to patch already patched functions. const bool kRelaxed = true; + // Record that we are starting the thunk setup code. + HKEY key = NULL; + DWORD disposition = 0; + LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, + kRegistryBeaconPath, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_QUERY_VALUE | KEY_SET_VALUE, + NULL, + &key, + &disposition); + if (result == ERROR_SUCCESS) { + DWORD blacklist_state = BLACKLIST_THUNK_SETUP; + ::RegSetValueEx(key, + kBeaconState, + 0, + REG_DWORD, + reinterpret_cast<LPBYTE>(&blacklist_state), + sizeof(blacklist_state)); + } else { + key = NULL; + } + // Create a thunk via the appropriate ServiceResolver instance. sandbox::ServiceResolverThunk* thunk; #if defined(_WIN64) @@ -332,8 +372,10 @@ bool Initialize(bool force) { if (!VirtualProtect(&g_thunk_storage, sizeof(g_thunk_storage), PAGE_EXECUTE_READWRITE, - &old_protect)) + &old_protect)) { + RecordSuccessfulThunkSetup(&key); return false; + } thunk->AllowLocalPatches(); @@ -355,6 +397,8 @@ bool Initialize(bool force) { PAGE_EXECUTE_READ, &old_protect); + RecordSuccessfulThunkSetup(&key); + return NT_SUCCESS(ret) && page_executable; } diff --git a/chrome_elf/blacklist/blacklist.h b/chrome_elf/blacklist/blacklist.h index 17a511d..7e01354 100644 --- a/chrome_elf/blacklist/blacklist.h +++ b/chrome_elf/blacklist/blacklist.h @@ -27,6 +27,12 @@ enum BlacklistState { // The blacklist setup code is running. If this is still set at startup, // it means the last setup crashed. BLACKLIST_SETUP_RUNNING, + // The blacklist thunk setup code is running. If this is still set at startup, + // it means the last setup crashed during thunk setup. + BLACKLIST_THUNK_SETUP, + // The blacklist code is currently intercepting MapViewOfSection. If this is + // still set at startup, it means we crashed during interception. + BLACKLIST_INTERCEPTING, // Always keep this at the end. BLACKLIST_STATE_MAX, }; diff --git a/chrome_elf/blacklist/blacklist_interceptions.cc b/chrome_elf/blacklist/blacklist_interceptions.cc index 6b01438..2be44e1 100644 --- a/chrome_elf/blacklist/blacklist_interceptions.cc +++ b/chrome_elf/blacklist/blacklist_interceptions.cc @@ -166,6 +166,21 @@ bool IsSameAsCurrentProcess(HANDLE process) { (::GetProcessId(process) == ::GetCurrentProcessId()); } +// Record that the interception completed succesfully and close the registry +// key handle since it is no longer needed. +void RecordSuccessfulInterception(HKEY* key, DWORD old_state) { + if (key != NULL) { + ::RegSetValueEx(*key, + blacklist::kBeaconState, + 0, + REG_DWORD, + reinterpret_cast<LPBYTE>(&old_state), + sizeof(old_state)); + ::RegCloseKey(*key); + key = NULL; + } +} + } // namespace namespace blacklist { @@ -196,12 +211,53 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection( SECTION_INHERIT inherit, ULONG allocation_type, ULONG protect) { + // Record that we are starting an interception. + HKEY key = NULL; + DWORD disposition = 0; + LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER, + kRegistryBeaconPath, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_QUERY_VALUE | KEY_SET_VALUE, + NULL, + &key, + &disposition); + + DWORD old_blacklist_state = BLACKLIST_DISABLED; + if (result == ERROR_SUCCESS) { + DWORD old_blacklist_state_size = sizeof(old_blacklist_state); + DWORD type = 0; + result = ::RegQueryValueEx(key, + kBeaconState, + 0, + &type, + reinterpret_cast<LPBYTE>(&old_blacklist_state), + &old_blacklist_state_size); + + if (result != ERROR_SUCCESS) { + old_blacklist_state = BLACKLIST_ENABLED; + } + + DWORD blacklist_state = BLACKLIST_INTERCEPTING; + ::RegSetValueEx(key, + kBeaconState, + 0, + REG_DWORD, + reinterpret_cast<LPBYTE>(&blacklist_state), + sizeof(blacklist_state)); + } else { + key = NULL; + } + + NTSTATUS ret = orig_MapViewOfSection(section, process, base, zero_bits, commit_size, offset, view_size, inherit, allocation_type, protect); if (!NT_SUCCESS(ret) || !IsSameAsCurrentProcess(process) || !IsModuleValidImageSection(section, base, offset, view_size)) { + RecordSuccessfulInterception(&key, old_blacklist_state); return ret; } @@ -224,8 +280,9 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI BlNtMapViewOfSection( g_nt_unmap_view_of_section_func(process, *base); ret = STATUS_UNSUCCESSFUL; } - } + + RecordSuccessfulInterception(&key, old_blacklist_state); return ret; } |