Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | 5 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 SIZE_T size, | 141 SIZE_T size, |
| 142 DWORD new_protect, | 142 DWORD new_protect, |
| 143 PDWORD old_protect); | 143 PDWORD old_protect); |
| 144 | 144 |
| 145 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free = | 145 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free = |
| 146 LAZY_INSTANCE_INITIALIZER; | 146 LAZY_INSTANCE_INITIALIZER; |
| 147 BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address, | 147 BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address, |
| 148 SIZE_T size, | 148 SIZE_T size, |
| 149 DWORD free_type); | 149 DWORD free_type); |
| 150 | 150 |
| 151 const size_t kMaxPluginExecMemSize = 64 * 1024 * 1024; // 64mb. | 151 const size_t kMaxPluginExecMemSize = 16 * 1024 * 1024; // 16mb. |
| 152 const DWORD kExecPageMask = PAGE_EXECUTE | PAGE_EXECUTE_READ | | 152 const DWORD kExecPageMask = PAGE_EXECUTE | PAGE_EXECUTE_READ | |
| 153 PAGE_EXECUTE_READWRITE; | 153 PAGE_EXECUTE_READWRITE; |
| 154 static volatile intptr_t g_max_exec_mem_size; | 154 static volatile intptr_t g_max_exec_mem_size; |
| 155 static intptr_t g_exec_mem_size = 0; | 155 static intptr_t g_exec_mem_size = 0; |
| 156 static scoped_ptr<base::Lock> g_exec_mem_lock; | 156 static scoped_ptr<base::Lock> g_exec_mem_lock; |
| 157 | 157 |
| 158 size_t UpdateExecMemSize(intptr_t size) { | 158 size_t UpdateExecMemSize(intptr_t size) { |
| 159 base::AutoLock locked(*g_exec_mem_lock); | 159 base::AutoLock locked(*g_exec_mem_lock); |
| 160 g_exec_mem_size += size; | 160 g_exec_mem_size += size; |
| 161 // Floor to zero since shutdown may unmap pages created before our hooks. | 161 // Floor to zero since shutdown may unmap pages created before our hooks. |
| 162 if (g_exec_mem_size < 0) | 162 if (g_exec_mem_size < 0) |
| 163 g_exec_mem_size = 0; | 163 g_exec_mem_size = 0; |
| 164 if (g_exec_mem_size > g_max_exec_mem_size) | 164 if (g_exec_mem_size > g_max_exec_mem_size) |
| 165 g_max_exec_mem_size = g_exec_mem_size; | 165 g_max_exec_mem_size = g_exec_mem_size; |
| 166 | 166 |
| 167 return g_exec_mem_size; | 167 return g_exec_mem_size; |
| 168 } | 168 } |
| 169 | 169 |
| 170 // Throw a unique exception when the JIT limit is hit. | |
| 171 inline void RaiseJITException() { | |
| 172 static const ULONG parameters[] = {1, 0xabad1dea /* 2880249322 */ }; | |
| 173 ::RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, | |
| 174 2, parameters); | |
|
cpu_(ooo_6.6-7.5)
2012/02/23 01:06:10
instead of 2 use arraysize of whatever it is calle
| |
| 175 } | |
| 176 | |
| 170 // http://crbug.com/16114 | 177 // http://crbug.com/16114 |
| 171 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow | 178 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow |
| 172 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. | 179 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. |
| 173 // Doing so allows removing NPP_SetWindow call during painting a windowless | 180 // Doing so allows removing NPP_SetWindow call during painting a windowless |
| 174 // plugin, which otherwise could trigger layout change while painting by | 181 // plugin, which otherwise could trigger layout change while painting by |
| 175 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. | 182 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. |
| 176 // TODO(dglazkov): If this approach doesn't produce regressions, move class to | 183 // TODO(dglazkov): If this approach doesn't produce regressions, move class to |
| 177 // webplugin_delegate_impl.h and implement for other platforms. | 184 // webplugin_delegate_impl.h and implement for other platforms. |
| 178 class DrawableContextEnforcer { | 185 class DrawableContextEnforcer { |
| 179 public: | 186 public: |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 // We need to track RX memory usage in plugins to prevent JIT spraying attacks. | 357 // We need to track RX memory usage in plugins to prevent JIT spraying attacks. |
| 351 // This is done by hooking VirtualAlloc, VirtualProtect, and VirtualFree. | 358 // This is done by hooking VirtualAlloc, VirtualProtect, and VirtualFree. |
| 352 LPVOID WINAPI WebPluginDelegateImpl::VirtualAllocPatch(LPVOID address, | 359 LPVOID WINAPI WebPluginDelegateImpl::VirtualAllocPatch(LPVOID address, |
| 353 SIZE_T size, | 360 SIZE_T size, |
| 354 DWORD allocation_type, | 361 DWORD allocation_type, |
| 355 DWORD protect) { | 362 DWORD protect) { |
| 356 void* p = g_iat_orig_virtual_alloc(address, size, allocation_type, protect); | 363 void* p = g_iat_orig_virtual_alloc(address, size, allocation_type, protect); |
| 357 if (size && p && (protect & kExecPageMask)) { | 364 if (size && p && (protect & kExecPageMask)) { |
| 358 bool limit_exceeded = UpdateExecMemSize(static_cast<intptr_t>(size)) > | 365 bool limit_exceeded = UpdateExecMemSize(static_cast<intptr_t>(size)) > |
| 359 kMaxPluginExecMemSize; | 366 kMaxPluginExecMemSize; |
| 360 #ifndef NDEBUG // TODO(jschuh): Do this in release after we get numbers. | |
| 361 if (limit_exceeded) | 367 if (limit_exceeded) |
| 362 ::DebugBreak(); | 368 RaiseJITException(); |
| 363 #endif | |
| 364 } | 369 } |
| 365 return p; | 370 return p; |
| 366 } | 371 } |
| 367 | 372 |
| 368 BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address, | 373 BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address, |
| 369 SIZE_T size, | 374 SIZE_T size, |
| 370 DWORD new_protect, | 375 DWORD new_protect, |
| 371 PDWORD old_protect) { | 376 PDWORD old_protect) { |
| 372 if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) { | 377 if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) { |
| 373 bool is_exec = !!(new_protect & kExecPageMask); | 378 bool is_exec = !!(new_protect & kExecPageMask); |
| 374 bool was_exec = !!(*old_protect & kExecPageMask); | 379 bool was_exec = !!(*old_protect & kExecPageMask); |
| 375 if (is_exec && !was_exec) { | 380 if (is_exec && !was_exec) { |
| 376 bool limit_exceeded = UpdateExecMemSize(static_cast<intptr_t>(size)) > | 381 bool limit_exceeded = UpdateExecMemSize(static_cast<intptr_t>(size)) > |
| 377 kMaxPluginExecMemSize; | 382 kMaxPluginExecMemSize; |
| 378 #ifndef NDEBUG // TODO(jschuh): Do this in release after we get numbers. | |
| 379 if (limit_exceeded) | 383 if (limit_exceeded) |
| 380 ::DebugBreak(); | 384 RaiseJITException(); |
| 381 #endif | |
| 382 } else if (!is_exec && was_exec) { | 385 } else if (!is_exec && was_exec) { |
| 383 UpdateExecMemSize(-(static_cast<intptr_t>(size))); | 386 UpdateExecMemSize(-(static_cast<intptr_t>(size))); |
| 384 } | 387 } |
| 385 | 388 |
| 386 return TRUE; | 389 return TRUE; |
| 387 } | 390 } |
| 388 | 391 |
| 389 return FALSE; | 392 return FALSE; |
| 390 } | 393 } |
| 391 | 394 |
| (...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1702 ::ReleaseCapture(); | 1705 ::ReleaseCapture(); |
| 1703 break; | 1706 break; |
| 1704 | 1707 |
| 1705 default: | 1708 default: |
| 1706 break; | 1709 break; |
| 1707 } | 1710 } |
| 1708 } | 1711 } |
| 1709 | 1712 |
| 1710 } // namespace npapi | 1713 } // namespace npapi |
| 1711 } // namespace webkit | 1714 } // namespace webkit |
| OLD | NEW |