Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / sandbox / win / sandbox_poc / pocdll / handles.cc
1 // Copyright (c) 2006-2010 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 "sandbox/win/sandbox_poc/pocdll/exports.h"
6 #include "sandbox/win/sandbox_poc/pocdll/utils.h"
7 #include "sandbox/win/tools/finder/ntundoc.h"
8
9 // This file contains the tests used to verify the security of handles in
10 // the process
11
12 NTQUERYOBJECT NtQueryObject;
13 NTQUERYINFORMATIONFILE NtQueryInformationFile;
14 NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
15
16 void POCDLL_API TestGetHandle(HANDLE log) {
17   HandleToFile handle2file;
18   FILE *output = handle2file.Translate(log, "w");
19
20   // Initialize the NTAPI functions we need
21   HMODULE ntdll_handle = ::GetModuleHandle(L"ntdll.dll");
22   if (!ntdll_handle) {
23     fprintf(output, "[ERROR] Cannot load ntdll.dll. Error %ld\r\n",
24             ::GetLastError());
25     return;
26   }
27
28   NtQueryObject = reinterpret_cast<NTQUERYOBJECT>(
29                       GetProcAddress(ntdll_handle, "NtQueryObject"));
30   NtQueryInformationFile = reinterpret_cast<NTQUERYINFORMATIONFILE>(
31                       GetProcAddress(ntdll_handle, "NtQueryInformationFile"));
32   NtQuerySystemInformation = reinterpret_cast<NTQUERYSYSTEMINFORMATION>(
33                       GetProcAddress(ntdll_handle, "NtQuerySystemInformation"));
34
35   if (!NtQueryObject || !NtQueryInformationFile || !NtQuerySystemInformation) {
36     fprintf(output, "[ERROR] Cannot load all NT functions. Error %ld\r\n",
37                     ::GetLastError());
38     return;
39   }
40
41   // Get the number of handles on the system
42   DWORD buffer_size = 0;
43   SYSTEM_HANDLE_INFORMATION_EX temp_info;
44   NTSTATUS status = NtQuerySystemInformation(
45       SystemHandleInformation, &temp_info, sizeof(temp_info),
46       &buffer_size);
47   if (!buffer_size) {
48     fprintf(output, "[ERROR] Get the number of handles. Error 0x%lX\r\n",
49                     status);
50     return;
51   }
52
53   SYSTEM_HANDLE_INFORMATION_EX *system_handles =
54       reinterpret_cast<SYSTEM_HANDLE_INFORMATION_EX*>(new BYTE[buffer_size]);
55
56   status = NtQuerySystemInformation(SystemHandleInformation, system_handles,
57                                     buffer_size, &buffer_size);
58   if (STATUS_SUCCESS != status) {
59     fprintf(output, "[ERROR] Failed to get the handle list. Error 0x%lX\r\n",
60                     status);
61     delete [] system_handles;
62     return;
63   }
64
65   for (ULONG i = 0; i < system_handles->NumberOfHandles; ++i) {
66     USHORT h = system_handles->Information[i].Handle;
67     if (system_handles->Information[i].ProcessId != ::GetCurrentProcessId())
68       continue;
69
70     OBJECT_NAME_INFORMATION *name = NULL;
71     ULONG name_size = 0;
72     // Query the name information a first time to get the size of the name.
73     status = NtQueryObject(reinterpret_cast<HANDLE>(h),
74                            ObjectNameInformation,
75                            name,
76                            name_size,
77                            &name_size);
78
79     if (name_size) {
80       name = reinterpret_cast<OBJECT_NAME_INFORMATION *>(new BYTE[name_size]);
81
82       // Query the name information a second time to get the name of the
83       // object referenced by the handle.
84       status = NtQueryObject(reinterpret_cast<HANDLE>(h),
85                              ObjectNameInformation,
86                              name,
87                              name_size,
88                              &name_size);
89     }
90
91     PUBLIC_OBJECT_TYPE_INFORMATION *type = NULL;
92     ULONG type_size = 0;
93
94     // Query the object to get the size of the object type name.
95     status = NtQueryObject(reinterpret_cast<HANDLE>(h),
96                            ObjectTypeInformation,
97                            type,
98                            type_size,
99                            &type_size);
100     if (type_size) {
101       type = reinterpret_cast<PUBLIC_OBJECT_TYPE_INFORMATION *>(
102           new BYTE[type_size]);
103
104       // Query the type information a second time to get the object type
105       // name.
106       status = NtQueryObject(reinterpret_cast<HANDLE>(h),
107                              ObjectTypeInformation,
108                              type,
109                              type_size,
110                              &type_size);
111     }
112
113     // NtQueryObject cannot return the name for a file. In this case we
114     // need to ask NtQueryInformationFile
115     FILE_NAME_INFORMATION *file_name = NULL;
116     if (type && wcsncmp(L"File", type->TypeName.Buffer,
117                         (type->TypeName.Length /
118                         sizeof(type->TypeName.Buffer[0]))) == 0)  {
119       // This function does not return the size of the buffer. We need to
120       // iterate and always increase the buffer size until the function
121       // succeeds. (Or at least does not fail with STATUS_BUFFER_OVERFLOW)
122       ULONG size_file = MAX_PATH;
123       IO_STATUS_BLOCK status_block = {0};
124       do {
125         // Delete the previous buffer create. The buffer was too small
126         if (file_name) {
127           delete[] reinterpret_cast<BYTE*>(file_name);
128           file_name = NULL;
129         }
130
131         // Increase the buffer and do the call agan
132         size_file += MAX_PATH;
133         file_name = reinterpret_cast<FILE_NAME_INFORMATION *>(
134             new BYTE[size_file]);
135         status = NtQueryInformationFile(reinterpret_cast<HANDLE>(h),
136                                         &status_block,
137                                         file_name,
138                                         size_file,
139                                         FileNameInformation);
140       } while (status == STATUS_BUFFER_OVERFLOW);
141
142       if (STATUS_SUCCESS != status) {
143         if (file_name) {
144           delete[] file_name;
145           file_name = NULL;
146         }
147       }
148     }
149
150     if (file_name) {
151       UNICODE_STRING file_name_string;
152       file_name_string.Buffer = file_name->FileName;
153       file_name_string.Length = (USHORT)file_name->FileNameLength;
154       file_name_string.MaximumLength = (USHORT)file_name->FileNameLength;
155       fprintf(output, "[GRANTED] Handle 0x%4.4X Access: 0x%8.8lX "
156                       "Type: %-13wZ Path: %wZ\r\n",
157                       h,
158                       system_handles->Information[i].GrantedAccess,
159                       type ? &type->TypeName : NULL,
160                       &file_name_string);
161     } else {
162       fprintf(output, "[GRANTED] Handle 0x%4.4X Access: 0x%8.8lX "
163                       "Type: %-13wZ Path: %wZ\r\n",
164                       h,
165                       system_handles->Information[i].GrantedAccess,
166                       type ? &type->TypeName : NULL,
167                       name ? &name->ObjectName : NULL);
168     }
169
170     if (type) {
171       delete[] type;
172     }
173
174     if (file_name) {
175       delete[] file_name;
176     }
177
178     if (name) {
179       delete [] name;
180     }
181   }
182
183   if (system_handles) {
184     delete [] system_handles;
185   }
186 }