OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 <malloc.h> | |
6 #include "sandbox/win/sandbox_poc/pocdll/exports.h" | |
7 #include "sandbox/win/sandbox_poc/pocdll/utils.h" | |
8 | |
9 // This file contains the tests used to verify if it's possible to DOS or crash | |
10 // the machine. All tests that can impact the stability of the machine should | |
11 // be in this file. | |
12 | |
13 // Sleeps forever. this function is used to be the | |
14 // entry point for the threads created by the thread bombing function. | |
15 // This function never returns. | |
16 DWORD WINAPI MyThreadBombimgFunction(void* param) { | |
17 Sleep(INFINITE); | |
18 return 0; | |
19 } | |
20 | |
21 void POCDLL_API TestThreadBombing(HANDLE log) { | |
22 HandleToFile handle2file; | |
23 FILE* output = handle2file.Translate(log, "w"); | |
24 | |
25 // we stop after 5 errors in a row | |
26 int number_errors = 0; | |
27 for (int i = 0; i < 100000; ++i) { | |
28 DWORD tid; | |
29 // Create the thread and leak the handle. | |
30 HANDLE thread = ::CreateThread(NULL, // Default security attributes | |
31 NULL, // Stack size | |
32 MyThreadBombimgFunction, | |
33 NULL, // Parameter | |
34 0, // No creation flags | |
35 &tid); | |
36 if (thread) { | |
37 fprintf(output, "[GRANTED] Creating thread with tid 0x%lX\r\n", tid); | |
38 ::CloseHandle(thread); | |
39 number_errors = 0; | |
40 } else { | |
41 fprintf(output, "[BLOCKED] Creating thread. Error %ld\r\n", | |
42 ::GetLastError()); | |
43 number_errors++; | |
44 } | |
45 | |
46 if (number_errors >= 5) { | |
47 break; | |
48 } | |
49 } | |
50 } | |
51 | |
52 | |
53 // Executes a complex mathematical operation forever in a loop. This function | |
54 // is used as entry point for the threads created by TestTakeAllCpu. It it | |
55 // designed to take all CPU on the processor where the thread is running. | |
56 // The return value is always 0. | |
57 DWORD WINAPI TakeAllCpu(void* param) { | |
58 int cpt = 0; | |
59 for (;;) { | |
60 cpt += 2; | |
61 cpt /= 2; | |
62 cpt *= cpt; | |
63 cpt = cpt % 100; | |
64 cpt = cpt | (cpt * cpt); | |
65 } | |
66 } | |
67 | |
68 void POCDLL_API TestTakeAllCpu(HANDLE log) { | |
69 HandleToFile handle2file; | |
70 FILE* output = handle2file.Translate(log, "w"); | |
71 | |
72 DWORD_PTR process_mask = 0; | |
73 DWORD_PTR system_mask = 0; | |
74 if (::GetProcessAffinityMask(::GetCurrentProcess(), | |
75 &process_mask, | |
76 &system_mask)) { | |
77 DWORD_PTR affinity_mask = 1; | |
78 | |
79 while (system_mask) { | |
80 DWORD tid = 0; | |
81 | |
82 HANDLE thread = ::CreateThread(NULL, // Default security attributes. | |
83 NULL, // Stack size. | |
84 TakeAllCpu, | |
85 NULL, // Parameter. | |
86 0, // No creation flags. | |
87 &tid); | |
88 ::SetThreadAffinityMask(thread, affinity_mask); | |
89 | |
90 if (::SetThreadPriority(thread, REALTIME_PRIORITY_CLASS)) { | |
91 fprintf(output, "[GRANTED] Set thread(%ld) priority to Realtime\r\n", | |
92 tid); | |
93 } else { | |
94 fprintf(output, "[BLOCKED] Set thread(%ld) priority to Realtime\r\n", | |
95 tid); | |
96 } | |
97 | |
98 ::CloseHandle(thread); | |
99 | |
100 affinity_mask = affinity_mask << 1; | |
101 system_mask = system_mask >> 1; | |
102 } | |
103 } else { | |
104 fprintf(output, "[ERROR] Cannot get affinity mask. Error %ld\r\n", | |
105 ::GetLastError()); | |
106 } | |
107 } | |
108 | |
109 void POCDLL_API TestUseAllMemory(HANDLE log) { | |
110 HandleToFile handle2file; | |
111 FILE* output = handle2file.Translate(log, "w"); | |
112 | |
113 int number_errors = 0; | |
114 unsigned long memory_size = 0; | |
115 for (;;) { | |
116 DWORD* ptr_to_leak = reinterpret_cast<DWORD*>(malloc(1024 * 256)); | |
117 if (ptr_to_leak) { | |
118 memory_size += 256; | |
119 number_errors = 0; | |
120 } else { | |
121 number_errors++; | |
122 } | |
123 | |
124 // check if we have more than 5 errors in a row. If so, quit. | |
125 if (number_errors >= 5) { | |
126 fprintf(output, "[INFO] Created %lu kb of memory\r\n", memory_size); | |
127 return; | |
128 } | |
129 | |
130 Sleep(5); // 5ms to be able to see the progression easily with taskmgr. | |
131 } | |
132 } | |
133 | |
134 void POCDLL_API TestCreateObjects(HANDLE log) { | |
135 HandleToFile handle2file; | |
136 FILE* output = handle2file.Translate(log, "w"); | |
137 | |
138 int mutexes = 0; | |
139 int jobs = 0; | |
140 int events = 0; | |
141 for (int i = 0; i < 1000000; ++i) { | |
142 if (::CreateMutex(NULL, // Default security attributes. | |
143 TRUE, // We are the initial owner. | |
144 NULL)) { // No name. | |
145 mutexes++; | |
146 } | |
147 | |
148 if (::CreateJobObject(NULL, // Default security attributes. | |
149 NULL)) { // No name. | |
150 jobs++; | |
151 } | |
152 | |
153 if (::CreateEvent(NULL, // Default security attributes. | |
154 TRUE, // Manual Reset. | |
155 TRUE, // Object is signaled. | |
156 NULL)) { // No name. | |
157 events++; | |
158 } | |
159 } | |
160 | |
161 fprintf(output, "[GRANTED] Created %d mutexes, %d jobs and %d events for " | |
162 "a total of %d objects out of 3 000 000\r\n", mutexes, jobs, | |
163 events, mutexes + jobs + events); | |
164 } | |
165 | |
166 BOOL CALLBACK EnumWindowCallback(HWND hwnd, LPARAM output) { | |
167 DWORD pid; | |
168 ::GetWindowThreadProcessId(hwnd, &pid); | |
169 if (pid != ::GetCurrentProcessId()) { | |
170 wchar_t window_title[100 + 1] = {0}; | |
171 ::GetWindowText(hwnd, window_title, 100); | |
172 fprintf(reinterpret_cast<FILE*>(output), | |
173 "[GRANTED] Found window 0x%p with title %S\r\n", | |
174 hwnd, | |
175 window_title); | |
176 ::CloseWindow(hwnd); | |
177 } | |
178 | |
179 return TRUE; | |
180 } | |
181 | |
182 // Enumerates all the windows on the system and call the function to try to | |
183 // close them. The goal of this function is to try to kill the system by | |
184 // closing all windows. | |
185 // "output" is the stream used for logging. | |
186 void POCDLL_API TestCloseHWND(HANDLE log) { | |
187 HandleToFile handle2file; | |
188 FILE* output = handle2file.Translate(log, "w"); | |
189 | |
190 ::EnumWindows(EnumWindowCallback, PtrToLong(output)); | |
191 // TODO(nsylvain): find a way to know when the enum is finished | |
192 // before returning. | |
193 ::Sleep(3000); | |
194 } | |
OLD | NEW |