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