Home | History | Annotate | Download | only in common
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/common/handle_enumerator_win.h"
      6 
      7 #include <windows.h>
      8 #include <map>
      9 
     10 #include "base/command_line.h"
     11 #include "base/logging.h"
     12 #include "base/process/process.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "base/win/windows_version.h"
     15 #include "content/public/common/content_switches.h"
     16 #include "content/public/common/result_codes.h"
     17 #include "sandbox/win/src/handle_table.h"
     18 
     19 using base::ASCIIToUTF16;
     20 
     21 namespace content {
     22 namespace {
     23 
     24 typedef std::map<const base::string16, HandleType> HandleTypeMap;
     25 
     26 HandleTypeMap& MakeHandleTypeMap() {
     27   HandleTypeMap& handle_types = *(new HandleTypeMap());
     28   handle_types[sandbox::HandleTable::kTypeProcess] = ProcessHandle;
     29   handle_types[sandbox::HandleTable::kTypeThread] = ThreadHandle;
     30   handle_types[sandbox::HandleTable::kTypeFile] = FileHandle;
     31   handle_types[sandbox::HandleTable::kTypeDirectory] = DirectoryHandle;
     32   handle_types[sandbox::HandleTable::kTypeKey] = KeyHandle;
     33   handle_types[sandbox::HandleTable::kTypeWindowStation] = WindowStationHandle;
     34   handle_types[sandbox::HandleTable::kTypeDesktop] = DesktopHandle;
     35   handle_types[sandbox::HandleTable::kTypeService] = ServiceHandle;
     36   handle_types[sandbox::HandleTable::kTypeMutex] = MutexHandle;
     37   handle_types[sandbox::HandleTable::kTypeSemaphore] = SemaphoreHandle;
     38   handle_types[sandbox::HandleTable::kTypeEvent] = EventHandle;
     39   handle_types[sandbox::HandleTable::kTypeTimer] = TimerHandle;
     40   handle_types[sandbox::HandleTable::kTypeNamedPipe] = NamedPipeHandle;
     41   handle_types[sandbox::HandleTable::kTypeJobObject] = JobHandle;
     42   handle_types[sandbox::HandleTable::kTypeFileMap] = FileMapHandle;
     43   handle_types[sandbox::HandleTable::kTypeAlpcPort] = AlpcPortHandle;
     44 
     45   return handle_types;
     46 }
     47 
     48 }  // namespace
     49 
     50 const size_t kMaxHandleNameLength = 1024;
     51 
     52 void HandleEnumerator::EnumerateHandles() {
     53   sandbox::HandleTable handles;
     54   std::string process_type =
     55       base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
     56           switches::kProcessType);
     57   base::string16 output = ASCIIToUTF16(process_type);
     58   output.append(ASCIIToUTF16(" process - Handles at shutdown:\n"));
     59   for (sandbox::HandleTable::Iterator sys_handle
     60       = handles.HandlesForProcess(::GetCurrentProcessId());
     61       sys_handle != handles.end(); ++sys_handle) {
     62     HandleType current_type = StringToHandleType(sys_handle->Type());
     63     if (!all_handles_ && (current_type != ProcessHandle &&
     64                           current_type != FileHandle &&
     65                           current_type != DirectoryHandle &&
     66                           current_type != KeyHandle &&
     67                           current_type != WindowStationHandle &&
     68                           current_type != DesktopHandle &&
     69                           current_type != ServiceHandle))
     70       continue;
     71 
     72     output += ASCIIToUTF16("[");
     73     output += sys_handle->Type();
     74     output += ASCIIToUTF16("] (");
     75     output += sys_handle->Name();
     76     output += ASCIIToUTF16(")\n");
     77     output += GetAccessString(current_type,
     78         sys_handle->handle_entry()->GrantedAccess);
     79   }
     80   DVLOG(0) << output;
     81 }
     82 
     83 HandleType StringToHandleType(const base::string16& type) {
     84   static HandleTypeMap handle_types = MakeHandleTypeMap();
     85   HandleTypeMap::iterator result = handle_types.find(type);
     86   return result != handle_types.end() ? result->second : OtherHandle;
     87 }
     88 
     89 base::string16 GetAccessString(HandleType handle_type,
     90                                            ACCESS_MASK access) {
     91   base::string16 output;
     92   if (access & GENERIC_READ)
     93     output.append(ASCIIToUTF16("\tGENERIC_READ\n"));
     94   if (access & GENERIC_WRITE)
     95     output.append(ASCIIToUTF16("\tGENERIC_WRITE\n"));
     96   if (access & GENERIC_EXECUTE)
     97     output.append(ASCIIToUTF16("\tGENERIC_EXECUTE\n"));
     98   if (access & GENERIC_ALL)
     99     output.append(ASCIIToUTF16("\tGENERIC_ALL\n"));
    100   if (access & DELETE)
    101     output.append(ASCIIToUTF16("\tDELETE\n"));
    102   if (access & READ_CONTROL)
    103     output.append(ASCIIToUTF16("\tREAD_CONTROL\n"));
    104   if (access & WRITE_DAC)
    105     output.append(ASCIIToUTF16("\tWRITE_DAC\n"));
    106   if (access & WRITE_OWNER)
    107     output.append(ASCIIToUTF16("\tWRITE_OWNER\n"));
    108   if (access & SYNCHRONIZE)
    109     output.append(ASCIIToUTF16("\tSYNCHRONIZE\n"));
    110 
    111   switch (handle_type) {
    112     case ProcessHandle:
    113       if (access & PROCESS_CREATE_PROCESS)
    114         output.append(ASCIIToUTF16("\tPROCESS_CREATE_PROCESS\n"));
    115       if (access & PROCESS_CREATE_THREAD)
    116         output.append(ASCIIToUTF16("\tPROCESS_CREATE_THREAD\n"));
    117       if (access & PROCESS_DUP_HANDLE)
    118         output.append(ASCIIToUTF16("\tPROCESS_DUP_HANDLE\n"));
    119       if (access & PROCESS_QUERY_INFORMATION)
    120         output.append(ASCIIToUTF16("\tPROCESS_QUERY_INFORMATION\n"));
    121       if (access & PROCESS_QUERY_LIMITED_INFORMATION)
    122         output.append(ASCIIToUTF16("\tPROCESS_QUERY_LIMITED_INFORMATION\n"));
    123       if (access & PROCESS_SET_INFORMATION)
    124         output.append(ASCIIToUTF16("\tPROCESS_SET_INFORMATION\n"));
    125       if (access & PROCESS_SET_QUOTA)
    126         output.append(ASCIIToUTF16("\tPROCESS_SET_QUOTA\n"));
    127       if (access & PROCESS_SUSPEND_RESUME)
    128         output.append(ASCIIToUTF16("\tPROCESS_SUSPEND_RESUME\n"));
    129       if (access & PROCESS_TERMINATE)
    130         output.append(ASCIIToUTF16("\tPROCESS_TERMINATE\n"));
    131       if (access & PROCESS_VM_OPERATION)
    132         output.append(ASCIIToUTF16("\tPROCESS_VM_OPERATION\n"));
    133       if (access & PROCESS_VM_READ)
    134         output.append(ASCIIToUTF16("\tPROCESS_VM_READ\n"));
    135       if (access & PROCESS_VM_WRITE)
    136         output.append(ASCIIToUTF16("\tPROCESS_VM_WRITE\n"));
    137       break;
    138     case ThreadHandle:
    139       if (access & THREAD_DIRECT_IMPERSONATION)
    140         output.append(ASCIIToUTF16("\tTHREAD_DIRECT_IMPERSONATION\n"));
    141       if (access & THREAD_GET_CONTEXT)
    142         output.append(ASCIIToUTF16("\tTHREAD_GET_CONTEXT\n"));
    143       if (access & THREAD_IMPERSONATE)
    144         output.append(ASCIIToUTF16("\tTHREAD_IMPERSONATE\n"));
    145       if (access & THREAD_QUERY_INFORMATION )
    146         output.append(ASCIIToUTF16("\tTHREAD_QUERY_INFORMATION\n"));
    147       if (access & THREAD_QUERY_LIMITED_INFORMATION)
    148         output.append(ASCIIToUTF16("\tTHREAD_QUERY_LIMITED_INFORMATION\n"));
    149       if (access & THREAD_SET_CONTEXT)
    150         output.append(ASCIIToUTF16("\tTHREAD_SET_CONTEXT\n"));
    151       if (access & THREAD_SET_INFORMATION)
    152         output.append(ASCIIToUTF16("\tTHREAD_SET_INFORMATION\n"));
    153       if (access & THREAD_SET_LIMITED_INFORMATION)
    154         output.append(ASCIIToUTF16("\tTHREAD_SET_LIMITED_INFORMATION\n"));
    155       if (access & THREAD_SET_THREAD_TOKEN)
    156         output.append(ASCIIToUTF16("\tTHREAD_SET_THREAD_TOKEN\n"));
    157       if (access & THREAD_SUSPEND_RESUME)
    158         output.append(ASCIIToUTF16("\tTHREAD_SUSPEND_RESUME\n"));
    159       if (access & THREAD_TERMINATE)
    160         output.append(ASCIIToUTF16("\tTHREAD_TERMINATE\n"));
    161       break;
    162     case FileHandle:
    163       if (access & FILE_APPEND_DATA)
    164         output.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n"));
    165       if (access & FILE_EXECUTE)
    166         output.append(ASCIIToUTF16("\tFILE_EXECUTE\n"));
    167       if (access & FILE_READ_ATTRIBUTES)
    168         output.append(ASCIIToUTF16("\tFILE_READ_ATTRIBUTES\n"));
    169       if (access & FILE_READ_DATA)
    170         output.append(ASCIIToUTF16("\tFILE_READ_DATA\n"));
    171       if (access & FILE_READ_EA)
    172         output.append(ASCIIToUTF16("\tFILE_READ_EA\n"));
    173       if (access & FILE_WRITE_ATTRIBUTES)
    174         output.append(ASCIIToUTF16("\tFILE_WRITE_ATTRIBUTES\n"));
    175       if (access & FILE_WRITE_DATA)
    176         output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n"));
    177       if (access & FILE_WRITE_EA)
    178         output.append(ASCIIToUTF16("\tFILE_WRITE_EA\n"));
    179       break;
    180     case DirectoryHandle:
    181       if (access & FILE_ADD_FILE)
    182         output.append(ASCIIToUTF16("\tFILE_ADD_FILE\n"));
    183       if (access & FILE_ADD_SUBDIRECTORY)
    184         output.append(ASCIIToUTF16("\tFILE_ADD_SUBDIRECTORY\n"));
    185       if (access & FILE_APPEND_DATA)
    186         output.append(ASCIIToUTF16("\tFILE_APPEND_DATA\n"));
    187       if (access & FILE_DELETE_CHILD)
    188         output.append(ASCIIToUTF16("\tFILE_DELETE_CHILD\n"));
    189       if (access & FILE_LIST_DIRECTORY)
    190         output.append(ASCIIToUTF16("\tFILE_LIST_DIRECTORY\n"));
    191       if (access & FILE_READ_DATA)
    192         output.append(ASCIIToUTF16("\tFILE_READ_DATA\n"));
    193       if (access & FILE_TRAVERSE)
    194         output.append(ASCIIToUTF16("\tFILE_TRAVERSE\n"));
    195       if (access & FILE_WRITE_DATA)
    196         output.append(ASCIIToUTF16("\tFILE_WRITE_DATA\n"));
    197       break;
    198     case KeyHandle:
    199       if (access & KEY_CREATE_LINK)
    200         output.append(ASCIIToUTF16("\tKEY_CREATE_LINK\n"));
    201       if (access & KEY_CREATE_SUB_KEY)
    202         output.append(ASCIIToUTF16("\tKEY_CREATE_SUB_KEY\n"));
    203       if (access & KEY_ENUMERATE_SUB_KEYS)
    204         output.append(ASCIIToUTF16("\tKEY_ENUMERATE_SUB_KEYS\n"));
    205       if (access & KEY_EXECUTE)
    206         output.append(ASCIIToUTF16("\tKEY_EXECUTE\n"));
    207       if (access & KEY_NOTIFY)
    208         output.append(ASCIIToUTF16("\tKEY_NOTIFY\n"));
    209       if (access & KEY_QUERY_VALUE)
    210         output.append(ASCIIToUTF16("\tKEY_QUERY_VALUE\n"));
    211       if (access & KEY_READ)
    212         output.append(ASCIIToUTF16("\tKEY_READ\n"));
    213       if (access & KEY_SET_VALUE)
    214         output.append(ASCIIToUTF16("\tKEY_SET_VALUE\n"));
    215       if (access & KEY_WOW64_32KEY)
    216         output.append(ASCIIToUTF16("\tKEY_WOW64_32KEY\n"));
    217       if (access & KEY_WOW64_64KEY)
    218         output.append(ASCIIToUTF16("\tKEY_WOW64_64KEY\n"));
    219       break;
    220     case WindowStationHandle:
    221       if (access & WINSTA_ACCESSCLIPBOARD)
    222         output.append(ASCIIToUTF16("\tWINSTA_ACCESSCLIPBOARD\n"));
    223       if (access & WINSTA_ACCESSGLOBALATOMS)
    224         output.append(ASCIIToUTF16("\tWINSTA_ACCESSGLOBALATOMS\n"));
    225       if (access & WINSTA_CREATEDESKTOP)
    226         output.append(ASCIIToUTF16("\tWINSTA_CREATEDESKTOP\n"));
    227       if (access & WINSTA_ENUMDESKTOPS)
    228         output.append(ASCIIToUTF16("\tWINSTA_ENUMDESKTOPS\n"));
    229       if (access & WINSTA_ENUMERATE)
    230         output.append(ASCIIToUTF16("\tWINSTA_ENUMERATE\n"));
    231       if (access & WINSTA_EXITWINDOWS)
    232         output.append(ASCIIToUTF16("\tWINSTA_EXITWINDOWS\n"));
    233       if (access & WINSTA_READATTRIBUTES)
    234         output.append(ASCIIToUTF16("\tWINSTA_READATTRIBUTES\n"));
    235       if (access & WINSTA_READSCREEN)
    236         output.append(ASCIIToUTF16("\tWINSTA_READSCREEN\n"));
    237       if (access & WINSTA_WRITEATTRIBUTES)
    238         output.append(ASCIIToUTF16("\tWINSTA_WRITEATTRIBUTES\n"));
    239       break;
    240     case DesktopHandle:
    241       if (access & DESKTOP_CREATEMENU)
    242         output.append(ASCIIToUTF16("\tDESKTOP_CREATEMENU\n"));
    243       if (access & DESKTOP_CREATEWINDOW)
    244         output.append(ASCIIToUTF16("\tDESKTOP_CREATEWINDOW\n"));
    245       if (access & DESKTOP_ENUMERATE)
    246         output.append(ASCIIToUTF16("\tDESKTOP_ENUMERATE\n"));
    247       if (access & DESKTOP_HOOKCONTROL)
    248         output.append(ASCIIToUTF16("\tDESKTOP_HOOKCONTROL\n"));
    249       if (access & DESKTOP_JOURNALPLAYBACK)
    250         output.append(ASCIIToUTF16("\tDESKTOP_JOURNALPLAYBACK\n"));
    251       if (access & DESKTOP_JOURNALRECORD)
    252         output.append(ASCIIToUTF16("\tDESKTOP_JOURNALRECORD\n"));
    253       if (access & DESKTOP_READOBJECTS)
    254         output.append(ASCIIToUTF16("\tDESKTOP_READOBJECTS\n"));
    255       if (access & DESKTOP_SWITCHDESKTOP)
    256         output.append(ASCIIToUTF16("\tDESKTOP_SWITCHDESKTOP\n"));
    257       if (access & DESKTOP_WRITEOBJECTS)
    258         output.append(ASCIIToUTF16("\tDESKTOP_WRITEOBJECTS\n"));
    259       break;
    260     case ServiceHandle:
    261       if (access & SC_MANAGER_CREATE_SERVICE)
    262         output.append(ASCIIToUTF16("\tSC_MANAGER_CREATE_SERVICE\n"));
    263       if (access & SC_MANAGER_CONNECT)
    264         output.append(ASCIIToUTF16("\tSC_MANAGER_CONNECT\n"));
    265       if (access & SC_MANAGER_ENUMERATE_SERVICE )
    266         output.append(ASCIIToUTF16("\tSC_MANAGER_ENUMERATE_SERVICE\n"));
    267       if (access & SC_MANAGER_LOCK)
    268         output.append(ASCIIToUTF16("\tSC_MANAGER_LOCK\n"));
    269       if (access & SC_MANAGER_MODIFY_BOOT_CONFIG )
    270         output.append(ASCIIToUTF16("\tSC_MANAGER_MODIFY_BOOT_CONFIG\n"));
    271       if (access & SC_MANAGER_QUERY_LOCK_STATUS )
    272         output.append(ASCIIToUTF16("\tSC_MANAGER_QUERY_LOCK_STATUS\n"));
    273       break;
    274     case EventHandle:
    275       if (access & EVENT_MODIFY_STATE)
    276         output.append(ASCIIToUTF16("\tEVENT_MODIFY_STATE\n"));
    277       break;
    278     case MutexHandle:
    279       if (access & MUTEX_MODIFY_STATE)
    280         output.append(ASCIIToUTF16("\tMUTEX_MODIFY_STATE\n"));
    281       break;
    282     case SemaphoreHandle:
    283       if (access & SEMAPHORE_MODIFY_STATE)
    284         output.append(ASCIIToUTF16("\tSEMAPHORE_MODIFY_STATE\n"));
    285       break;
    286     case TimerHandle:
    287       if (access & TIMER_MODIFY_STATE)
    288         output.append(ASCIIToUTF16("\tTIMER_MODIFY_STATE\n"));
    289       if (access & TIMER_QUERY_STATE)
    290         output.append(ASCIIToUTF16("\tTIMER_QUERY_STATE\n"));
    291       break;
    292     case NamedPipeHandle:
    293       if (access & PIPE_ACCESS_INBOUND)
    294         output.append(ASCIIToUTF16("\tPIPE_ACCESS_INBOUND\n"));
    295       if (access & PIPE_ACCESS_OUTBOUND)
    296         output.append(ASCIIToUTF16("\tPIPE_ACCESS_OUTBOUND\n"));
    297       break;
    298     case JobHandle:
    299       if (access & JOB_OBJECT_ASSIGN_PROCESS)
    300         output.append(ASCIIToUTF16("\tJOB_OBJECT_ASSIGN_PROCESS\n"));
    301       if (access & JOB_OBJECT_QUERY)
    302         output.append(ASCIIToUTF16("\tJOB_OBJECT_QUERY\n"));
    303       if (access & JOB_OBJECT_SET_ATTRIBUTES)
    304         output.append(ASCIIToUTF16("\tJOB_OBJECT_SET_ATTRIBUTES\n"));
    305       if (access & JOB_OBJECT_SET_SECURITY_ATTRIBUTES)
    306         output.append(ASCIIToUTF16("\tJOB_OBJECT_SET_SECURITY_ATTRIBUTES\n"));
    307       if (access & JOB_OBJECT_TERMINATE)
    308         output.append(ASCIIToUTF16("\tJOB_OBJECT_TERMINATE\n"));
    309       break;
    310     case FileMapHandle:
    311       if (access & FILE_MAP_EXECUTE)
    312         output.append(ASCIIToUTF16("\tFILE_MAP_EXECUTE\n"));
    313       if (access & FILE_MAP_READ)
    314         output.append(ASCIIToUTF16("\tFILE_MAP_READ\n"));
    315       if (access & FILE_MAP_WRITE)
    316         output.append(ASCIIToUTF16("\tFILE_MAP_WRITE\n"));
    317       break;
    318   }
    319   return output;
    320 }
    321 
    322 }  // namespace content
    323