blob: 52fa902bd39a76c8d9af77898cdb30ad3067cc12 [file] [log] [blame]
[email protected]d4a8ca482013-10-30 21:06:401// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]8bf1048012012-02-08 01:22:182// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d4a8ca482013-10-30 21:06:405#include "content/browser/frame_host/debug_urls.h"
[email protected]8bf1048012012-02-08 01:22:186
[email protected]029bd942013-01-22 08:30:337#include <vector>
8
Sebastien Marchandf8cbfab2019-01-25 16:02:309#include "base/bind.h"
[email protected]47752982014-07-29 08:01:4310#include "base/command_line.h"
[email protected]b4b34792014-06-14 08:29:3711#include "base/debug/asan_invalid_access.h"
12#include "base/debug/profiler.h"
Peter Collingbourne6ce4b212019-02-15 22:19:5013#include "base/sanitizer_buildflags.h"
[email protected]74ebfb12013-06-07 20:48:0014#include "base/strings/utf_string_conversions.h"
erikwright811f1b02015-04-17 18:58:3615#include "base/synchronization/waitable_event.h"
Eric Seckler8652dcd52018-09-20 10:42:2816#include "base/task/post_task.h"
erikwrightcf61cd792015-04-23 14:35:2017#include "base/threading/thread_restrictions.h"
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5118#include "build/build_config.h"
[email protected]47752982014-07-29 08:01:4319#include "cc/base/switches.h"
sadrulb428f6b2017-03-03 19:28:3220#include "content/browser/gpu/gpu_process_host.h"
Eric Seckler8652dcd52018-09-20 10:42:2821#include "content/public/browser/browser_task_traits.h"
[email protected]029bd942013-01-22 08:30:3322#include "content/public/browser/browser_thread.h"
[email protected]73270292013-08-09 03:48:0723#include "content/public/common/content_constants.h"
[email protected]8bf1048012012-02-08 01:22:1824#include "content/public/common/url_constants.h"
Scott Violet02e38b92018-03-27 23:42:1425#include "ppapi/buildflags/buildflags.h"
[email protected]707e1c42013-07-09 21:18:5826#include "url/gurl.h"
[email protected]8bf1048012012-02-08 01:22:1827
brettw4b461082016-11-19 18:55:1628#if BUILDFLAG(ENABLE_PLUGINS)
alokp76ed9ed2017-01-26 00:17:4429#include "content/browser/ppapi_plugin_process_host.h" // nogncheck
Aran Gilman37d11632019-10-08 23:07:1530#include "ppapi/proxy/ppapi_messages.h" // nogncheck
thestigc4cac8f2014-09-04 21:17:5031#endif
32
Will Harriseb4a6ff2018-07-25 18:36:5233#if defined(OS_WIN)
34#include "base/debug/invalid_access_win.h"
35#endif
36
[email protected]8bf1048012012-02-08 01:22:1837namespace content {
38
pmonette3955a4f2016-01-29 22:24:3739class ScopedAllowWaitForDebugURL {
40 private:
Etienne Pierre-dorayaffab0d2018-11-12 15:51:1141 base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
pmonette3955a4f2016-01-29 22:24:3742};
43
[email protected]029bd942013-01-22 08:30:3344namespace {
45
[email protected]b4b34792014-06-14 08:29:3746// Define the Asan debug URLs.
47const char kAsanCrashDomain[] = "crash";
48const char kAsanHeapOverflow[] = "/browser-heap-overflow";
49const char kAsanHeapUnderflow[] = "/browser-heap-underflow";
50const char kAsanUseAfterFree[] = "/browser-use-after-free";
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5151
52#if defined(OS_WIN)
[email protected]b4b34792014-06-14 08:29:3753const char kAsanCorruptHeapBlock[] = "/browser-corrupt-heap-block";
54const char kAsanCorruptHeap[] = "/browser-corrupt-heap";
erikwright3d483052015-03-06 13:14:4455#endif
erikwright420a0902015-02-26 21:16:1756
[email protected]029bd942013-01-22 08:30:3357void HandlePpapiFlashDebugURL(const GURL& url) {
brettw4b461082016-11-19 18:55:1658#if BUILDFLAG(ENABLE_PLUGINS)
csharrisona3bd0b32016-10-19 18:40:4859 bool crash = url == kChromeUIPpapiFlashCrashURL;
[email protected]029bd942013-01-22 08:30:3360
61 std::vector<PpapiPluginProcessHost*> hosts;
Aran Gilman37d11632019-10-08 23:07:1562 PpapiPluginProcessHost::FindByName(base::UTF8ToUTF16(kFlashPluginName),
63 &hosts);
jdoerrie55ec69d2018-10-08 13:34:4664 for (auto iter = hosts.begin(); iter != hosts.end(); ++iter) {
[email protected]029bd942013-01-22 08:30:3365 if (crash)
66 (*iter)->Send(new PpapiMsg_Crash());
67 else
68 (*iter)->Send(new PpapiMsg_Hang());
69 }
70#endif
71}
72
[email protected]b4b34792014-06-14 08:29:3773bool IsAsanDebugURL(const GURL& url) {
[email protected]b4b34792014-06-14 08:29:3774 if (!(url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
Aran Gilman37d11632019-10-08 23:07:1575 url.DomainIs(kAsanCrashDomain) && url.has_path())) {
[email protected]b4b34792014-06-14 08:29:3776 return false;
77 }
78
csharrison88b3b712016-11-14 23:12:3579 if (url.path_piece() == kAsanHeapOverflow ||
80 url.path_piece() == kAsanHeapUnderflow ||
81 url.path_piece() == kAsanUseAfterFree) {
[email protected]b4b34792014-06-14 08:29:3782 return true;
83 }
84
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5185#if defined(OS_WIN)
csharrison88b3b712016-11-14 23:12:3586 if (url.path_piece() == kAsanCorruptHeapBlock ||
87 url.path_piece() == kAsanCorruptHeap) {
[email protected]b4b34792014-06-14 08:29:3788 return true;
csharrison88b3b712016-11-14 23:12:3589 }
[email protected]b4b34792014-06-14 08:29:3790#endif
91
92 return false;
93}
94
95bool HandleAsanDebugURL(const GURL& url) {
Peter Collingbourne6ce4b212019-02-15 22:19:5096#if defined(ADDRESS_SANITIZER) || BUILDFLAG(IS_HWASAN)
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:5197#if defined(OS_WIN)
csharrison88b3b712016-11-14 23:12:3598 if (url.path_piece() == kAsanCorruptHeapBlock) {
[email protected]b4b34792014-06-14 08:29:3799 base::debug::AsanCorruptHeapBlock();
100 return true;
csharrison88b3b712016-11-14 23:12:35101 } else if (url.path_piece() == kAsanCorruptHeap) {
[email protected]b4b34792014-06-14 08:29:37102 base::debug::AsanCorruptHeap();
103 return true;
104 }
Sigurdur Asgeirsson69d0bcd2018-03-29 21:50:51105#endif // OS_WIN
[email protected]b4b34792014-06-14 08:29:37106
csharrison88b3b712016-11-14 23:12:35107 if (url.path_piece() == kAsanHeapOverflow) {
[email protected]b4b34792014-06-14 08:29:37108 base::debug::AsanHeapOverflow();
csharrison88b3b712016-11-14 23:12:35109 } else if (url.path_piece() == kAsanHeapUnderflow) {
[email protected]b4b34792014-06-14 08:29:37110 base::debug::AsanHeapUnderflow();
csharrison88b3b712016-11-14 23:12:35111 } else if (url.path_piece() == kAsanUseAfterFree) {
[email protected]b4b34792014-06-14 08:29:37112 base::debug::AsanHeapUseAfterFree();
113 } else {
114 return false;
115 }
116#endif
117
118 return true;
119}
120
pmonette3955a4f2016-01-29 22:24:37121void HangCurrentThread() {
122 ScopedAllowWaitForDebugURL allow_wait;
gabd6f9bff2016-06-02 13:48:20123 base::WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
124 base::WaitableEvent::InitialState::NOT_SIGNALED)
125 .Wait();
pmonette3955a4f2016-01-29 22:24:37126}
[email protected]b4b34792014-06-14 08:29:37127
[email protected]029bd942013-01-22 08:30:33128} // namespace
129
Ian Vollick9dda0522019-09-11 02:24:29130bool HandleDebugURL(const GURL& url,
131 ui::PageTransition transition,
132 bool is_explicit_navigation) {
133 // We want to handle the debug URL if the user explicitly navigated to this
134 // URL, unless kEnableGpuBenchmarking is enabled by Telemetry.
[email protected]479278702014-08-11 20:32:09135 bool is_telemetry_navigation =
136 base::CommandLine::ForCurrentProcess()->HasSwitch(
137 cc::switches::kEnableGpuBenchmarking) &&
vmiura20fa51a32015-10-27 21:39:34138 (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED));
[email protected]8bf1048012012-02-08 01:22:18139
Ian Vollicka5ff9c202019-07-22 21:19:03140 if (!is_explicit_navigation && !is_telemetry_navigation)
[email protected]47752982014-07-29 08:01:43141 return false;
[email protected]eabfe1912014-05-12 10:07:28142
[email protected]b4b34792014-06-14 08:29:37143 if (IsAsanDebugURL(url))
144 return HandleAsanDebugURL(url);
145
csharrisona3bd0b32016-10-19 18:40:48146 if (url == kChromeUIBrowserCrashURL) {
[email protected]8bf1048012012-02-08 01:22:18147 // Induce an intentional crash in the browser process.
148 CHECK(false);
149 return true;
150 }
151
Will Harriseb4a6ff2018-07-25 18:36:52152#if defined(OS_WIN)
153 if (url == kChromeUIBrowserHeapCorruptionURL) {
154 // Induce an intentional heap corruption in the browser process.
155 base::debug::win::TerminateWithHeapCorruption();
156 return true;
157 }
158#endif
159
csharrisona3bd0b32016-10-19 18:40:48160 if (url == kChromeUIBrowserUIHang) {
pmonette3955a4f2016-01-29 22:24:37161 HangCurrentThread();
162 return true;
163 }
164
csharrisona3bd0b32016-10-19 18:40:48165 if (url == kChromeUIDelayedBrowserUIHang) {
pmonette3955a4f2016-01-29 22:24:37166 // Webdriver-safe url to hang the ui thread. Webdriver waits for the onload
167 // event in javascript which needs a little more time to fire.
Sami Kyostila8e4d5a92019-08-02 12:45:05168 base::PostDelayedTask(FROM_HERE, {BrowserThread::UI},
169 base::BindOnce(&HangCurrentThread),
170 base::TimeDelta::FromSeconds(2));
erikwright811f1b02015-04-17 18:58:36171 return true;
172 }
173
csharrisona3bd0b32016-10-19 18:40:48174 if (url == kChromeUIGpuCleanURL) {
Maggie Chen867b5822019-05-16 02:03:14175 GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED,
sadrulb428f6b2017-03-03 19:28:32176 false /* force_create */,
177 base::Bind([](GpuProcessHost* host) {
sadrule6f6e102017-03-11 01:09:56178 if (host)
179 host->gpu_service()->DestroyAllChannels();
sadrulb428f6b2017-03-03 19:28:32180 }));
[email protected]8bf1048012012-02-08 01:22:18181 return true;
182 }
183
csharrisona3bd0b32016-10-19 18:40:48184 if (url == kChromeUIGpuCrashURL) {
Maggie Chen867b5822019-05-16 02:03:14185 GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED,
sadrule6f6e102017-03-11 01:09:56186 false /* force_create */,
187 base::Bind([](GpuProcessHost* host) {
188 if (host)
189 host->gpu_service()->Crash();
190 }));
[email protected]8bf1048012012-02-08 01:22:18191 return true;
192 }
193
boliu7a81c2522017-02-03 03:41:04194#if defined(OS_ANDROID)
195 if (url == kChromeUIGpuJavaCrashURL) {
Maggie Chen867b5822019-05-16 02:03:14196 GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED,
sadrulb428f6b2017-03-03 19:28:32197 false /* force_create */,
198 base::Bind([](GpuProcessHost* host) {
sadrule6f6e102017-03-11 01:09:56199 if (host)
200 host->gpu_service()->ThrowJavaException();
sadrulb428f6b2017-03-03 19:28:32201 }));
boliu7a81c2522017-02-03 03:41:04202 return true;
203 }
204#endif
205
csharrisona3bd0b32016-10-19 18:40:48206 if (url == kChromeUIGpuHangURL) {
Maggie Chen867b5822019-05-16 02:03:14207 GpuProcessHost::CallOnIO(GPU_PROCESS_KIND_SANDBOXED,
sadrule6f6e102017-03-11 01:09:56208 false /* force_create */,
209 base::Bind([](GpuProcessHost* host) {
210 if (host)
211 host->gpu_service()->Hang();
212 }));
[email protected]8bf1048012012-02-08 01:22:18213 return true;
214 }
215
csharrisona3bd0b32016-10-19 18:40:48216 if (url == kChromeUIPpapiFlashCrashURL || url == kChromeUIPpapiFlashHangURL) {
Sami Kyostila8e4d5a92019-08-02 12:45:05217 base::PostTask(FROM_HERE, {BrowserThread::IO},
218 base::BindOnce(&HandlePpapiFlashDebugURL, url));
[email protected]029bd942013-01-22 08:30:33219 return true;
220 }
221
[email protected]8bf1048012012-02-08 01:22:18222 return false;
223}
224
[email protected]8bf1048012012-02-08 01:22:18225} // namespace content