diff options
Diffstat (limited to 'content/browser')
9 files changed, 48 insertions, 533 deletions
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index e438989..1462e10 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc @@ -21,7 +21,6 @@ #if defined(OS_WIN) #include "base/file_path.h" -#include "content/browser/handle_enumerator_win.h" #include "content/common/sandbox_policy.h" #elif defined(OS_MACOSX) #include "content/browser/mach_broker_mac.h" @@ -237,20 +236,6 @@ class ChildProcessLauncher::Context if (!terminate_child_on_shutdown_) return; -#if defined(OS_WIN) - const CommandLine& browser_command_line = - *CommandLine::ForCurrentProcess(); - if (browser_command_line.HasSwitch(switches::kAuditHandles) || - browser_command_line.HasSwitch(switches::kAuditAllHandles)) { - scoped_refptr<content::HandleEnumerator> handle_enum( - new content::HandleEnumerator(process_.handle(), - browser_command_line.HasSwitch(switches::kAuditAllHandles))); - handle_enum->RunHandleEnumeration(); - process_.set_handle(base::kNullProcessHandle); - return; - } -#endif - // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! So // don't this on the UI/IO threads. BrowserThread::PostTask( diff --git a/content/browser/handle_enumerator_win.cc b/content/browser/handle_enumerator_win.cc deleted file mode 100644 index 0d5ba51..0000000 --- a/content/browser/handle_enumerator_win.cc +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (c) 2011 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 "content/browser/handle_enumerator_win.h" - -#include <windows.h> -#include <map> - -#include "base/logging.h" -#include "base/process.h" -#include "base/process_util.h" -#include "base/utf_string_conversions.h" -#include "base/win/windows_version.h" -#include "content/browser/browser_child_process_host.h" -#include "content/browser/browser_thread.h" -#include "content/browser/renderer_host/render_process_host.h" -#include "content/common/result_codes.h" -#include "sandbox/src/handle_table.h" - -namespace { - -typedef std::map<const string16, content::HandleType> HandleTypeMap; - -HandleTypeMap& MakeHandleTypeMap() { - HandleTypeMap& handle_types = *(new HandleTypeMap()); - handle_types[sandbox::HandleTable::kTypeProcess] = content::ProcessHandle; - handle_types[sandbox::HandleTable::kTypeThread] = content::ThreadHandle; - handle_types[sandbox::HandleTable::kTypeFile] = content::FileHandle; - handle_types[sandbox::HandleTable::kTypeDirectory] = - content::DirectoryHandle; - handle_types[sandbox::HandleTable::kTypeKey] = content::KeyHandle; - handle_types[sandbox::HandleTable::kTypeWindowStation] = - content::WindowStationHandle; - handle_types[sandbox::HandleTable::kTypeDesktop] = content::DesktopHandle; - handle_types[sandbox::HandleTable::kTypeService] = content::ServiceHandle; - handle_types[sandbox::HandleTable::kTypeMutex] = content::MutexHandle; - handle_types[sandbox::HandleTable::kTypeSemaphore] = - content::SemaphoreHandle; - handle_types[sandbox::HandleTable::kTypeEvent] = content::EventHandle; - handle_types[sandbox::HandleTable::kTypeTimer] = content::TimerHandle; - handle_types[sandbox::HandleTable::kTypeNamedPipe] = - content::NamedPipeHandle; - handle_types[sandbox::HandleTable::kTypeJobObject] = content::JobHandle; - handle_types[sandbox::HandleTable::kTypeFileMap] = content::FileMapHandle; - handle_types[sandbox::HandleTable::kTypeAlpcPort] = - content::AlpcPortHandle; - - return handle_types; -} - -} // namespace - -namespace content { - -const wchar_t kNtdllDllName[] = L"ntdll.dll"; -const size_t kMaxHandleNameLength = 1024; - -void HandleEnumerator::EnumerateHandles() { - sandbox::HandleTable handles; - - string16 output = ProcessTypeString(type_); - output.append(ASCIIToUTF16(" Process - Handles at shutdown:\n")); - for (sandbox::HandleTable::Iterator sys_handle - = handles.HandlesForProcess(::GetProcessId(handle_)); - sys_handle != handles.end(); ++sys_handle) { - HandleType current_type = StringToHandleType(sys_handle->Type()); - if (!all_handles_ && (current_type != ProcessHandle && - current_type != FileHandle && - current_type != DirectoryHandle && - current_type != KeyHandle && - current_type != WindowStationHandle && - current_type != DesktopHandle && - current_type != ServiceHandle)) - continue; - - output += ASCIIToUTF16("["); - output += sys_handle->Type(); - output += ASCIIToUTF16("] ("); - output += sys_handle->Name(); - output += ASCIIToUTF16(")\n"); - output += GetAccessString(current_type, - sys_handle->handle_entry()->GrantedAccess); - } - LOG(INFO) << output; -} - -void HandleEnumerator::RunHandleEnumeration() { - DCHECK(status_ == Starting); - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) - FindProcessOnIOThread(); - else if (BrowserThread::CurrentlyOn(BrowserThread::UI)) - FindProcessOnUIThread(); - else - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, - &HandleEnumerator::FindProcessOnIOThread)); -} - -void HandleEnumerator::FindProcessOnIOThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) { - if (iter->handle() == handle_) { - type_ = iter->type(); - status_ = Finished; - break; - } - } - - if (status_ == Starting) { - status_ = InProgress; - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, - &HandleEnumerator::FindProcessOnUIThread)); - } else { - status_ = Finished; - BrowserThread::PostTask( - BrowserThread::PROCESS_LAUNCHER, FROM_HERE, - NewRunnableMethod(this, - &HandleEnumerator::EnumerateHandlesAndTerminateProcess)); - } -} - -void HandleEnumerator::FindProcessOnUIThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - for (RenderProcessHost::iterator renderer_iter( - RenderProcessHost::AllHostsIterator()); !renderer_iter.IsAtEnd(); - renderer_iter.Advance()) { - RenderProcessHost* render_process_host = renderer_iter.GetCurrentValue(); - if (render_process_host->GetHandle() == handle_) { - type_ = ChildProcessInfo::RENDER_PROCESS; - status_ = Finished; - break; - } - } - - if (status_ == Starting) { - status_ = InProgress; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, - &HandleEnumerator::FindProcessOnIOThread)); - } else { - status_ = Finished; - BrowserThread::PostTask( - BrowserThread::PROCESS_LAUNCHER, FROM_HERE, - NewRunnableMethod(this, - &HandleEnumerator::EnumerateHandlesAndTerminateProcess)); - } -} - -void HandleEnumerator::EnumerateHandlesAndTerminateProcess() { - HandleEnumerator::EnumerateHandles(); - base::Process process(handle_); - process.Terminate(content::RESULT_CODE_NORMAL_EXIT); - process.Close(); -} - -string16 ProcessTypeString(ChildProcessInfo::ProcessType process_type) { - switch (process_type) { - case ChildProcessInfo::UNKNOWN_PROCESS: - return ASCIIToUTF16("Unknown"); - case ChildProcessInfo::BROWSER_PROCESS: - return ASCIIToUTF16("Browser"); - case ChildProcessInfo::RENDER_PROCESS: - return ASCIIToUTF16("Renderer"); - case ChildProcessInfo::PLUGIN_PROCESS: - return ASCIIToUTF16("Plugin"); - case ChildProcessInfo::WORKER_PROCESS: - return ASCIIToUTF16("Worker"); - case ChildProcessInfo::NACL_LOADER_PROCESS: - return ASCIIToUTF16("NaCL Loader"); - case ChildProcessInfo::UTILITY_PROCESS: - return ASCIIToUTF16("Utility"); - case ChildProcessInfo::PROFILE_IMPORT_PROCESS: - return ASCIIToUTF16("Profile Import"); - case ChildProcessInfo::ZYGOTE_PROCESS: - return ASCIIToUTF16("Zygote"); - case ChildProcessInfo::SANDBOX_HELPER_PROCESS: - return ASCIIToUTF16("Sandbox Helper"); - case ChildProcessInfo::NACL_BROKER_PROCESS: - return ASCIIToUTF16("NaCL Broker"); - case ChildProcessInfo::GPU_PROCESS: - return ASCIIToUTF16("GPU"); - case ChildProcessInfo::PPAPI_PLUGIN_PROCESS: - return ASCIIToUTF16("Pepper Plugin"); - case ChildProcessInfo::PPAPI_BROKER_PROCESS: - return ASCIIToUTF16("Pepper Broker"); - default: - return string16(); - } -} - -HandleType StringToHandleType(const string16& type) { - static HandleTypeMap handle_types = MakeHandleTypeMap(); - HandleTypeMap::iterator result = handle_types.find(type); - return result != handle_types.end() ? result->second : OtherHandle; -} - -string16 GetAccessString(HandleType handle_type, - ACCESS_MASK access) { - string16 output; - if (access & GENERIC_READ) - output.append(ASCIIToUTF16("\tGENERIC_READ\n")); - if (access & GENERIC_WRITE) - output.append(ASCIIToUTF16("\tGENERIC_WRITE\n")); - if (access & GENERIC_EXECUTE) - output.append(ASCIIToUTF16("\tGENERIC_EXECUTE\n")); - if (access & GENERIC_ALL) - output.append(ASCIIToUTF16("\tGENERIC_ALL\n")); - if (access & DELETE) - output.append(ASCIIToUTF16("\tDELETE\n")); - if (access & READ_CONTROL) - output.append(ASCIIToUTF16("\tREAD_CONTROL\n")); - if (access & WRITE_DAC) - output.append(ASCIIToUTF16("\tWRITE_DAC\n")); - if (access & WRITE_OWNER) - output.append(ASCIIToUTF16("\tWRITE_OWNER\n")); - if (access & SYNCHRONIZE) - output.append(ASCIIToUTF16("\tSYNCHRONIZE\n")); - - switch (handle_type) { - case ProcessHandle: - if (access & PROCESS_CREATE_PROCESS) - output.append(ASCIIToUTF16("\tPROCESS_CREATE_PROCESS\n")); - if (access & PROCESS_CREATE_THREAD) - output.append(ASCIIToUTF16("\tPROCESS_CREATE_THREAD\n")); - if (access & PROCESS_DUP_HANDLE) - output.append(ASCIIToUTF16("\tPROCESS_DUP_HANDLE\n")); - if (access & PROCESS_QUERY_INFORMATION) - output.append(ASCIIToUTF16("\tPROCESS_QUERY_INFORMATION\n")); - if (access & PROCESS_QUERY_LIMITED_INFORMATION) - output.append(ASCIIToUTF16("\tPROCESS_QUERY_LIMITED_INFORMATION\n")); - if (access & PROCESS_SET_INFORMATION) - output.append(ASCIIToUTF16("\tPROCESS_SET_INFORMATION\n")); - if (access & PROCESS_SET_QUOTA) - output.append(ASCIIToUTF16("\tPROCESS_SET_QUOTA\n")); - if (access & PROCESS_SUSPEND_RESUME) - output.append(ASCIIToUTF16("\tPROCESS_SUSPEND_RESUME\n")); - if (access & PROCESS_TERMINATE) - output.append(ASCIIToUTF16("\tPROCESS_TERMINATE\n")); - if (access & PROCESS_VM_OPERATION) - output.append(ASCIIToUTF16("\tPROCESS_VM_OPERATION\n")); - if (access & PROCESS_VM_READ) - output.append(ASCIIToUTF16("\tPROCESS_VM_READ\n")); - if (access & PROCESS_VM_WRITE) - output.append(ASCIIToUTF16("\tPROCESS_VM_WRITE\n")); - break; - case ThreadHandle: - if (access & THREAD_DIRECT_IMPERSONATION) - output.append(ASCIIToUTF16("\tTHREAD_DIRECT_IMPERSONATION\n")); - if (access & THREAD_GET_CONTEXT) - output.append(ASCIIToUTF16("\tTHREAD_GET_CONTEXT\n")); - if (access & THREAD_IMPERSONATE) - output.append(ASCIIToUTF16("\tTHREAD_IMPERSONATE\n")); - if (access & THREAD_QUERY_INFORMATION ) - output.append(ASCIIToUTF16("\tTHREAD_QUERY_INFORMATION\n")); - if (access & THREAD_QUERY_LIMITED_INFORMATION) - output.append(ASCIIToUTF16("\tTHREAD_QUERY_LIMITED_INFORMATION\n")); - if (access & THREAD_SET_CONTEXT) - output.append(ASCIIToUTF16("\tTHREAD_SET_CONTEXT\n")); - if (access & THREAD_SET_INFORMATION) - output.append(ASCIIToUTF16("\tTHREAD_SET_INFORMATION\n")); - if (access & THREAD_SET_LIMITED_INFORMATION) - output.append(ASCIIToUTF16("\tTHREAD_SET_LIMITED_INFORMATION\n")); - if (access & THREAD_SET_THREAD_TOKEN) - output.append(ASCIIToUTF16("\tTHREAD_SET_THREAD_TOKEN\n")); - if (access & THREAD_SUSPEND_RESUME) - output.append(ASCIIToUTF16("\tTHREAD_SUSPEND_RESUME\n")); - if (access & THREAD_TERMINATE) - output.append(ASCIIToUTF16("\tTHREAD_TERMINATE\n")); - break; - case FileHandle: - if (access & FILE_APPEND_DATA) - output.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n")); - if (access & FILE_EXECUTE) - output.append(ASCIIToUTF16("\tFILE_EXECUTE\n")); - if (access & FILE_READ_ATTRIBUTES) - output.append(ASCIIToUTF16("\tFILE_READ_ATTRIBUTES\n")); - if (access & FILE_READ_DATA) - output.append(ASCIIToUTF16("\tFILE_READ_DATA\n")); - if (access & FILE_READ_EA) - output.append(ASCIIToUTF16("\tFILE_READ_EA\n")); - if (access & FILE_WRITE_ATTRIBUTES) - output.append(ASCIIToUTF16("\tFILE_WRITE_ATTRIBUTES\n")); - if (access & FILE_WRITE_DATA) - output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n")); - if (access & FILE_WRITE_EA) - output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n")); - if (access & FILE_WRITE_EA) - output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n")); - break; - case DirectoryHandle: - if (access & FILE_ADD_FILE) - output.append(ASCIIToUTF16("\tFILE_ADD_FILE\n")); - if (access & FILE_ADD_SUBDIRECTORY) - output.append(ASCIIToUTF16("\tFILE_ADD_SUBDIRECTORY\n")); - if (access & FILE_APPEND_DATA) - output.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n")); - if (access & FILE_DELETE_CHILD) - output.append(ASCIIToUTF16("\tFILE_DELETE_CHILD\n")); - if (access & FILE_LIST_DIRECTORY) - output.append(ASCIIToUTF16("\tFILE_LIST_DIRECTORY\n")); - if (access & FILE_READ_DATA) - output.append(ASCIIToUTF16("\tFILE_READ_DATA\n")); - if (access & FILE_TRAVERSE) - output.append(ASCIIToUTF16("\tFILE_TRAVERSE\n")); - if (access & FILE_WRITE_DATA) - output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n")); - break; - case KeyHandle: - if (access & KEY_CREATE_LINK) - output.append(ASCIIToUTF16("\tKEY_CREATE_LINK\n")); - if (access & KEY_CREATE_SUB_KEY) - output.append(ASCIIToUTF16("\tKEY_CREATE_SUB_KEY\n")); - if (access & KEY_ENUMERATE_SUB_KEYS) - output.append(ASCIIToUTF16("\tKEY_ENUMERATE_SUB_KEYS\n")); - if (access & KEY_EXECUTE) - output.append(ASCIIToUTF16("\tKEY_EXECUTE\n")); - if (access & KEY_NOTIFY) - output.append(ASCIIToUTF16("\tKEY_NOTIFY\n")); - if (access & KEY_QUERY_VALUE) - output.append(ASCIIToUTF16("\tKEY_QUERY_VALUE\n")); - if (access & KEY_READ) - output.append(ASCIIToUTF16("\tKEY_READ\n")); - if (access & KEY_SET_VALUE) - output.append(ASCIIToUTF16("\tKEY_SET_VALUE\n")); - if (access & KEY_WOW64_32KEY) - output.append(ASCIIToUTF16("\tKEY_WOW64_32KEY\n")); - if (access & KEY_WOW64_64KEY) - output.append(ASCIIToUTF16("\tKEY_WOW64_64KEY\n")); - break; - case WindowStationHandle: - if (access & WINSTA_ACCESSCLIPBOARD) - output.append(ASCIIToUTF16("\tWINSTA_ACCESSCLIPBOARD\n")); - if (access & WINSTA_ACCESSGLOBALATOMS) - output.append(ASCIIToUTF16("\tWINSTA_ACCESSGLOBALATOMS\n")); - if (access & WINSTA_CREATEDESKTOP) - output.append(ASCIIToUTF16("\tWINSTA_CREATEDESKTOP\n")); - if (access & WINSTA_ENUMDESKTOPS) - output.append(ASCIIToUTF16("\tWINSTA_ENUMDESKTOPS\n")); - if (access & WINSTA_ENUMERATE) - output.append(ASCIIToUTF16("\tWINSTA_ENUMERATE\n")); - if (access & WINSTA_EXITWINDOWS) - output.append(ASCIIToUTF16("\tWINSTA_EXITWINDOWS\n")); - if (access & WINSTA_READATTRIBUTES) - output.append(ASCIIToUTF16("\tWINSTA_READATTRIBUTES\n")); - if (access & WINSTA_READSCREEN) - output.append(ASCIIToUTF16("\tWINSTA_READSCREEN\n")); - if (access & WINSTA_WRITEATTRIBUTES) - output.append(ASCIIToUTF16("\tWINSTA_WRITEATTRIBUTES\n")); - break; - case DesktopHandle: - if (access & DESKTOP_CREATEMENU) - output.append(ASCIIToUTF16("\tDESKTOP_CREATEMENU\n")); - if (access & DESKTOP_CREATEWINDOW) - output.append(ASCIIToUTF16("\tDESKTOP_CREATEWINDOW\n")); - if (access & DESKTOP_ENUMERATE) - output.append(ASCIIToUTF16("\tDESKTOP_ENUMERATE\n")); - if (access & DESKTOP_HOOKCONTROL) - output.append(ASCIIToUTF16("\tDESKTOP_HOOKCONTROL\n")); - if (access & DESKTOP_JOURNALPLAYBACK) - output.append(ASCIIToUTF16("\tDESKTOP_JOURNALPLAYBACK\n")); - if (access & DESKTOP_JOURNALRECORD) - output.append(ASCIIToUTF16("\tDESKTOP_JOURNALRECORD\n")); - if (access & DESKTOP_READOBJECTS) - output.append(ASCIIToUTF16("\tDESKTOP_READOBJECTS\n")); - if (access & DESKTOP_SWITCHDESKTOP) - output.append(ASCIIToUTF16("\tDESKTOP_SWITCHDESKTOP\n")); - if (access & DESKTOP_WRITEOBJECTS) - output.append(ASCIIToUTF16("\tDESKTOP_WRITEOBJECTS\n")); - break; - case ServiceHandle: - if (access & SC_MANAGER_CREATE_SERVICE) - output.append(ASCIIToUTF16("\tSC_MANAGER_CREATE_SERVICE\n")); - if (access & SC_MANAGER_CONNECT) - output.append(ASCIIToUTF16("\tSC_MANAGER_CONNECT\n")); - if (access & SC_MANAGER_ENUMERATE_SERVICE ) - output.append(ASCIIToUTF16("\tSC_MANAGER_ENUMERATE_SERVICE\n")); - if (access & SC_MANAGER_LOCK) - output.append(ASCIIToUTF16("\tSC_MANAGER_LOCK\n")); - if (access & SC_MANAGER_MODIFY_BOOT_CONFIG ) - output.append(ASCIIToUTF16("\tSC_MANAGER_MODIFY_BOOT_CONFIG\n")); - if (access & SC_MANAGER_QUERY_LOCK_STATUS ) - output.append(ASCIIToUTF16("\tSC_MANAGER_QUERY_LOCK_STATUS\n")); - break; - case EventHandle: - if (access & EVENT_MODIFY_STATE) - output.append(ASCIIToUTF16("\tEVENT_MODIFY_STATE\n")); - break; - case MutexHandle: - if (access & MUTEX_MODIFY_STATE) - output.append(ASCIIToUTF16("\tMUTEX_MODIFY_STATE\n")); - break; - case SemaphoreHandle: - if (access & SEMAPHORE_MODIFY_STATE) - output.append(ASCIIToUTF16("\tSEMAPHORE_MODIFY_STATE\n")); - break; - case TimerHandle: - if (access & TIMER_MODIFY_STATE) - output.append(ASCIIToUTF16("\tTIMER_MODIFY_STATE\n")); - if (access & TIMER_QUERY_STATE) - output.append(ASCIIToUTF16("\tTIMER_QUERY_STATE\n")); - break; - case NamedPipeHandle: - if (access & PIPE_ACCESS_INBOUND) - output.append(ASCIIToUTF16("\tPIPE_ACCESS_INBOUND\n")); - if (access & PIPE_ACCESS_OUTBOUND) - output.append(ASCIIToUTF16("\tPIPE_ACCESS_OUTBOUND\n")); - break; - case JobHandle: - if (access & JOB_OBJECT_ASSIGN_PROCESS) - output.append(ASCIIToUTF16("\tJOB_OBJECT_ASSIGN_PROCESS\n")); - if (access & JOB_OBJECT_QUERY) - output.append(ASCIIToUTF16("\tJOB_OBJECT_QUERY\n")); - if (access & JOB_OBJECT_SET_ATTRIBUTES) - output.append(ASCIIToUTF16("\tJOB_OBJECT_SET_ATTRIBUTES\n")); - if (access & JOB_OBJECT_SET_SECURITY_ATTRIBUTES) - output.append(ASCIIToUTF16("\tJOB_OBJECT_SET_SECURITY_ATTRIBUTES\n")); - if (access & JOB_OBJECT_TERMINATE) - output.append(ASCIIToUTF16("\tJOB_OBJECT_TERMINATE\n")); - break; - case FileMapHandle: - if (access & FILE_MAP_EXECUTE) - output.append(ASCIIToUTF16("\tFILE_MAP_EXECUTE\n")); - if (access & FILE_MAP_READ) - output.append(ASCIIToUTF16("\tFILE_MAP_READ\n")); - if (access & FILE_MAP_WRITE) - output.append(ASCIIToUTF16("\tFILE_MAP_WRITE\n")); - break; - } - return output; -} - -} // namespace content diff --git a/content/browser/handle_enumerator_win.h b/content/browser/handle_enumerator_win.h deleted file mode 100644 index 12b426c..0000000 --- a/content/browser/handle_enumerator_win.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2011 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 CONTENT_BROWSER_HANDLE_ENUMERATOR_WIN_H_ -#define CONTENT_BROWSER_HANDLE_ENUMERATOR_WIN_H_ - -#include "base/memory/ref_counted.h" -#include "base/process.h" -#include "content/common/child_process_info.h" - -namespace content { - -enum HandleType { - ProcessHandle, - ThreadHandle, - FileHandle, - DirectoryHandle, - KeyHandle, - WindowStationHandle, - DesktopHandle, - ServiceHandle, - EventHandle, - MutexHandle, - SemaphoreHandle, - TimerHandle, - NamedPipeHandle, - JobHandle, - FileMapHandle, - AlpcPortHandle, - OtherHandle -}; - -static HandleType StringToHandleType(const string16& type); - -static string16 ProcessTypeString(ChildProcessInfo::ProcessType process_type); - -static string16 GetAccessString(HandleType handle_type, ACCESS_MASK access); - -class HandleEnumerator : public base::RefCountedThreadSafe<HandleEnumerator> { - public: - enum HandleEnumStatus { - Starting, - InProgress, - Finished - }; - - HandleEnumerator(base::ProcessHandle handle, bool all_handles): - handle_(handle), - type_(ChildProcessInfo::UNKNOWN_PROCESS), - status_(Starting), - all_handles_(all_handles) { } - - ChildProcessInfo::ProcessType type() const { return type_; } - - HandleEnumStatus status() const { return status_; } - - void RunHandleEnumeration(); - - void EnumerateHandles(); - - private: - void FindProcessOnIOThread(); - - void FindProcessOnUIThread(); - - void EnumerateHandlesAndTerminateProcess(); - - base::ProcessHandle handle_; - ChildProcessInfo::ProcessType type_; - HandleEnumStatus status_; - bool all_handles_; - - DISALLOW_COPY_AND_ASSIGN(HandleEnumerator); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_HANDLE_ENUMERATOR_WIN_H_ diff --git a/content/browser/renderer_host/browser_render_process_host.cc b/content/browser/renderer_host/browser_render_process_host.cc index 3abf9fc..2efd8fb 100644 --- a/content/browser/renderer_host/browser_render_process_host.cc +++ b/content/browser/renderer_host/browser_render_process_host.cc @@ -530,6 +530,8 @@ void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer( static const char* const kSwitchNames[] = { // We propagate the Chrome Frame command line here as well in case the // renderer is not run in the sandbox. + switches::kAuditAllHandles, + switches::kAuditHandles, switches::kChromeFrame, switches::kDisable3DAPIs, switches::kDisableAcceleratedCompositing, @@ -657,6 +659,15 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() { return true; } +void BrowserRenderProcessHost::DumpHandles() { +#if defined(OS_WIN) + Send(new ChildProcessMsg_DumpHandles()); + return; +#endif + + NOTIMPLEMENTED(); +} + // This is a platform specific function for mapping a transport DIB given its id TransportDIB* BrowserRenderProcessHost::MapTransportDIB( TransportDIB::Id dib_id) { @@ -757,6 +768,8 @@ bool BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP_EX(BrowserRenderProcessHost, msg, msg_is_ok) IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, OnShutdownRequest) + IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone, + OnDumpHandlesDone) IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged, SuddenTerminationChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, @@ -902,6 +915,10 @@ void BrowserRenderProcessHost::OnShutdownRequest() { Send(new ChildProcessMsg_Shutdown()); } +void BrowserRenderProcessHost::OnDumpHandlesDone() { + Cleanup(); +} + void BrowserRenderProcessHost::SuddenTerminationChanged(bool enabled) { set_sudden_termination_allowed(enabled); } diff --git a/content/browser/renderer_host/browser_render_process_host.h b/content/browser/renderer_host/browser_render_process_host.h index d209b03..97297e9 100644 --- a/content/browser/renderer_host/browser_render_process_host.h +++ b/content/browser/renderer_host/browser_render_process_host.h @@ -62,6 +62,7 @@ class BrowserRenderProcessHost : public RenderProcessHost, virtual void WidgetHidden(); virtual int VisibleWidgetCount() const; virtual bool FastShutdownIfPossible(); + virtual void DumpHandles(); virtual base::ProcessHandle GetHandle(); virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id); virtual void SetCompositingSurface( @@ -91,6 +92,7 @@ class BrowserRenderProcessHost : public RenderProcessHost, // Control message handlers. void OnShutdownRequest(); + void OnDumpHandlesDone(); void SuddenTerminationChanged(bool enabled); void OnUserMetricsRecordAction(const std::string& action); void OnRevealFolderInOS(const FilePath& path); diff --git a/content/browser/renderer_host/mock_render_process_host.cc b/content/browser/renderer_host/mock_render_process_host.cc index 87ec8de..d3f182d 100644 --- a/content/browser/renderer_host/mock_render_process_host.cc +++ b/content/browser/renderer_host/mock_render_process_host.cc @@ -74,6 +74,9 @@ bool MockRenderProcessHost::FastShutdownIfPossible() { return true; } +void MockRenderProcessHost::DumpHandles() { +} + base::ProcessHandle MockRenderProcessHost::GetHandle() { return base::kNullProcessHandle; } diff --git a/content/browser/renderer_host/mock_render_process_host.h b/content/browser/renderer_host/mock_render_process_host.h index 03e163e..c719472 100644 --- a/content/browser/renderer_host/mock_render_process_host.h +++ b/content/browser/renderer_host/mock_render_process_host.h @@ -50,6 +50,7 @@ class MockRenderProcessHost : public RenderProcessHost { virtual int VisibleWidgetCount() const; virtual void AddWord(const string16& word); virtual bool FastShutdownIfPossible(); + virtual void DumpHandles(); virtual base::ProcessHandle GetHandle(); virtual TransportDIB* GetTransportDIB(TransportDIB::Id dib_id); virtual void SetCompositingSurface( diff --git a/content/browser/renderer_host/render_process_host.cc b/content/browser/renderer_host/render_process_host.cc index 44e52231..958a30d 100644 --- a/content/browser/renderer_host/render_process_host.cc +++ b/content/browser/renderer_host/render_process_host.cc @@ -4,12 +4,14 @@ #include "content/browser/renderer_host/render_process_host.h" +#include "base/command_line.h" #include "base/rand_util.h" #include "base/sys_info.h" #include "content/browser/browser_thread.h" #include "content/browser/child_process_security_policy.h" #include "content/common/child_process_info.h" #include "content/common/content_constants.h" +#include "content/common/content_switches.h" #include "content/common/notification_service.h" namespace { @@ -128,6 +130,23 @@ void RenderProcessHost::Release(int listener_id) { // Make sure that all associated resource requests are stopped. CancelResourceRequests(listener_id); +#if defined(OS_WIN) + // Dump the handle table if handle auditing is enabled. + const CommandLine& browser_command_line = + *CommandLine::ForCurrentProcess(); + if (browser_command_line.HasSwitch(switches::kAuditHandles) || + browser_command_line.HasSwitch(switches::kAuditAllHandles)) { + DumpHandles(); + + // We wait to close the channels until the child process has finished + // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone. + return; + } +#endif + Cleanup(); +} + +void RenderProcessHost::Cleanup() { // When no other owners of this object, we can delete ourselves if (listeners_.IsEmpty()) { NotificationService::current()->Notify( diff --git a/content/browser/renderer_host/render_process_host.h b/content/browser/renderer_host/render_process_host.h index 2164634..44d5dc8 100644 --- a/content/browser/renderer_host/render_process_host.h +++ b/content/browser/renderer_host/render_process_host.h @@ -104,6 +104,9 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Channel::Sender, // See Attach() void Release(int listener_id); + // Schedules the host for deletion and removes it from the all_hosts list. + void Cleanup(); + // Listeners should call this when they've sent a "Close" message and // they're waiting for a "Close_ACK", so that if the renderer process // goes away we'll know that it was intentional rather than a crash. @@ -213,6 +216,9 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Channel::Sender, // Returns True if it was able to do fast shutdown. virtual bool FastShutdownIfPossible() = 0; + // Dump the child process' handle table before shutting down. + virtual void DumpHandles() = 0; + // Returns the process object associated with the child process. In certain // tests or single-process mode, this will actually represent the current // process. |