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