Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: webkit/plugins/npapi/webplugin_delegate_impl_win.cc

Issue 9688022: Switch the plugin cap back to a reporting mode (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free = 138 base::LazyInstance<base::win::IATPatchFunction> g_iat_patch_virtual_free =
139 LAZY_INSTANCE_INITIALIZER; 139 LAZY_INSTANCE_INITIALIZER;
140 BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address, 140 BOOL (WINAPI *g_iat_orig_virtual_free)(LPVOID address,
141 SIZE_T size, 141 SIZE_T size,
142 DWORD free_type); 142 DWORD free_type);
143 143
144 const DWORD kExecPageMask = PAGE_EXECUTE_READ; 144 const DWORD kExecPageMask = PAGE_EXECUTE_READ;
145 static volatile intptr_t g_max_exec_mem_size; 145 static volatile intptr_t g_max_exec_mem_size;
146 static scoped_ptr<base::Lock> g_exec_mem_lock; 146 static scoped_ptr<base::Lock> g_exec_mem_lock;
147 147
148 bool UpdateExecMemSize(intptr_t size) { 148 void UpdateExecMemSize(intptr_t size) {
149 base::AutoLock locked(*g_exec_mem_lock); 149 base::AutoLock locked(*g_exec_mem_lock);
150 150
151 const intptr_t kMaxPluginExecMemSizeSpike = 80 * 1024 * 1024; // 80mb.
152 const DWORD kTimeLimit = 6; // 6 minute timeout.
153
154 static intptr_t s_exec_mem_size = 0; 151 static intptr_t s_exec_mem_size = 0;
155 static intptr_t s_exec_mem_size_old = 0;
156 static struct {
157 intptr_t size;
158 DWORD minutes;
159 } s_exec_mem_log[kTimeLimit];
160 static size_t s_old_idx;
161 static size_t s_now_idx;
162
163 DWORD now = ::GetTickCount() / (60 * 1000);
164
165 // Keep the size change history. This is done using a ring of entries with
166 // with the size and tick count
167 if (s_exec_mem_log[s_now_idx].minutes == now) {
168 s_exec_mem_log[s_now_idx].size += size;
169 } else {
170 // Move the index forward and clear the old entry if needed.
171 s_now_idx = (s_now_idx + 1) % kTimeLimit;
172 if (s_now_idx == s_old_idx) {
173 s_exec_mem_size_old = std::max(0, s_exec_mem_log[s_old_idx].size +
174 s_exec_mem_size_old);
175 ++s_old_idx;
176 }
177 s_exec_mem_log[s_now_idx].minutes = now;
178 s_exec_mem_log[s_now_idx].size = size;
179
180 // Expire any waiting old entries.
181 for (; s_old_idx != s_now_idx; s_old_idx = (s_old_idx + 1) % kTimeLimit) {
182 DWORD minutes = s_exec_mem_log[s_old_idx].minutes;
183 if (now - minutes < kTimeLimit)
184 break;
185 s_exec_mem_size_old = std::max(0, s_exec_mem_log[s_old_idx].size +
186 s_exec_mem_size_old);
187 }
188 }
189 152
190 // Floor to zero since shutdown may unmap pages created before our hooks. 153 // Floor to zero since shutdown may unmap pages created before our hooks.
191 s_exec_mem_size = std::max(0, s_exec_mem_size + size); 154 s_exec_mem_size = std::max(0, s_exec_mem_size + size);
192 if (s_exec_mem_size > g_max_exec_mem_size) 155 if (s_exec_mem_size > g_max_exec_mem_size)
193 g_max_exec_mem_size = s_exec_mem_size; 156 g_max_exec_mem_size = s_exec_mem_size;
194
195
196 if ((s_exec_mem_size - s_exec_mem_size_old) > kMaxPluginExecMemSizeSpike)
197 return false;
198
199 return true;
200 }
201
202 // Throw a unique exception when the JIT limit is hit.
203 inline void RaiseJITException() {
204 static const ULONG parameters[] = {1, 0xabad1dea /* 2880249322 */ };
205 ::RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE,
206 arraysize(parameters), parameters);
207 } 157 }
208 158
209 // http://crbug.com/16114 159 // http://crbug.com/16114
210 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow 160 // Enforces providing a valid device context in NPWindow, so that NPP_SetWindow
211 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL. 161 // is never called with NPNWindoTypeDrawable and NPWindow set to NULL.
212 // Doing so allows removing NPP_SetWindow call during painting a windowless 162 // Doing so allows removing NPP_SetWindow call during painting a windowless
213 // plugin, which otherwise could trigger layout change while painting by 163 // plugin, which otherwise could trigger layout change while painting by
214 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes. 164 // invoking NPN_Evaluate. Which would cause bad, bad crashes. Bad crashes.
215 // TODO(dglazkov): If this approach doesn't produce regressions, move class to 165 // TODO(dglazkov): If this approach doesn't produce regressions, move class to
216 // webplugin_delegate_impl.h and implement for other platforms. 166 // webplugin_delegate_impl.h and implement for other platforms.
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 // We need to track RX memory usage in plugins to prevent JIT spraying attacks. 339 // We need to track RX memory usage in plugins to prevent JIT spraying attacks.
390 // This is done by hooking VirtualProtect and VirtualFree. 340 // This is done by hooking VirtualProtect and VirtualFree.
391 BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address, 341 BOOL WINAPI WebPluginDelegateImpl::VirtualProtectPatch(LPVOID address,
392 SIZE_T size, 342 SIZE_T size,
393 DWORD new_protect, 343 DWORD new_protect,
394 PDWORD old_protect) { 344 PDWORD old_protect) {
395 if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) { 345 if (g_iat_orig_virtual_protect(address, size, new_protect, old_protect)) {
396 bool is_exec = new_protect == kExecPageMask; 346 bool is_exec = new_protect == kExecPageMask;
397 bool was_exec = *old_protect == kExecPageMask; 347 bool was_exec = *old_protect == kExecPageMask;
398 if (is_exec && !was_exec) { 348 if (is_exec && !was_exec) {
399 if (!UpdateExecMemSize(static_cast<intptr_t>(size))) 349 UpdateExecMemSize(static_cast<intptr_t>(size));
400 RaiseJITException();
401 } else if (!is_exec && was_exec) { 350 } else if (!is_exec && was_exec) {
402 UpdateExecMemSize(-(static_cast<intptr_t>(size))); 351 UpdateExecMemSize(-(static_cast<intptr_t>(size)));
403 } 352 }
404 353
405 return TRUE; 354 return TRUE;
406 } 355 }
407 356
408 return FALSE; 357 return FALSE;
409 } 358 }
410 359
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 ::ReleaseCapture(); 1664 ::ReleaseCapture();
1716 break; 1665 break;
1717 1666
1718 default: 1667 default:
1719 break; 1668 break;
1720 } 1669 }
1721 } 1670 }
1722 1671
1723 } // namespace npapi 1672 } // namespace npapi
1724 } // namespace webkit 1673 } // namespace webkit
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698