Chromium Code Reviews| Index: content/browser/security_exploit_browsertest.cc |
| diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc |
| index c515609c576f74cf8fbc60f1a6e8de11c3a19e90..2501f142346c5755c93223dd3739f3ca1a276460 100644 |
| --- a/content/browser/security_exploit_browsertest.cc |
| +++ b/content/browser/security_exploit_browsertest.cc |
| @@ -23,6 +23,7 @@ |
| #include "content/public/browser/content_browser_client.h" |
| #include "content/public/browser/interstitial_page.h" |
| #include "content/public/browser/interstitial_page_delegate.h" |
| +#include "content/public/browser/resource_dispatcher_host.h" |
| #include "content/public/browser/storage_partition.h" |
| #include "content/public/common/appcache_info.h" |
| #include "content/public/common/browser_side_navigation_policy.h" |
| @@ -37,6 +38,7 @@ |
| #include "ipc/ipc_security_test_util.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "net/test/embedded_test_server/embedded_test_server.h" |
| +#include "net/test/url_request/url_request_slow_download_job.h" |
| using IPC::IpcSecurityTestUtil; |
| @@ -44,6 +46,8 @@ namespace content { |
| namespace { |
| +const int kRequestIdNotPreviouslyUsed = 10000; |
|
mmenke
2016/01/28 21:12:33
nit: Should have a comment about this.
gzobqq
2016/01/30 07:18:57
Done.
|
| + |
| // This is a helper function for the tests which attempt to create a |
| // duplicate RenderViewHost or RenderWidgetHost. It tries to create two objects |
| // with the same process and routing ids, which causes a collision. |
| @@ -98,13 +102,11 @@ RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell, |
| return next_rfh->render_view_host(); |
| } |
| -ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { |
| +ResourceHostMsg_Request CreateXHRRequest(const char* url) { |
| ResourceHostMsg_Request request; |
| request.method = "GET"; |
| - request.url = GURL("http://bar.com/simple_page.html"); |
| - request.first_party_for_cookies = GURL(origin); |
| + request.url = GURL(url); |
| request.referrer_policy = blink::WebReferrerPolicyDefault; |
| - request.headers = base::StringPrintf("Origin: %s\r\n", origin); |
| request.load_flags = 0; |
| request.origin_pid = 0; |
| request.resource_type = RESOURCE_TYPE_XHR; |
| @@ -120,6 +122,49 @@ ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { |
| return request; |
| } |
| +ResourceHostMsg_Request CreateXHRRequestWithOrigin(const char* origin) { |
| + ResourceHostMsg_Request request = CreateXHRRequest("http://bar.com/simple_page.html"); |
|
mmenke
2016/01/28 21:12:33
nit: Split onto two lines, so no line is over 80
Charlie Reis
2016/01/28 22:05:16
Tip: Running "git cl format" should take care of t
gzobqq
2016/01/30 07:18:57
Done.
gzobqq
2016/01/30 07:18:57
That helps, thanks.
|
| + request.first_party_for_cookies = GURL(origin); |
| + request.headers = base::StringPrintf("Origin: %s\r\n", origin); |
| + return request; |
| +} |
| + |
| +void TryCreateDuplicateRequestIds(Shell *shell, bool block_loaders) { |
| + NavigateToURL(shell, GURL("http://foo.com/simple_page.html")); |
| + RenderFrameHost* web_rfh = shell->web_contents()->GetMainFrame(); |
|
Charlie Reis
2016/01/28 22:05:16
nit: s/web_rfh/rfh/
(The web_ prefix was useful i
gzobqq
2016/01/30 07:18:57
Done.
|
| + |
| + if (block_loaders) { |
| + // Test the case where loaders are placed into blocked_loaders_map_. |
| + int child_id = web_rfh->GetProcess()->GetID(); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&ResourceDispatcherHost::BlockRequestsForRoute, |
| + base::Unretained(ResourceDispatcherHost::Get()), |
| + child_id, web_rfh->GetRoutingID())); |
| + } |
| + |
| + // URLRequestSlowDownloadJob waits for another request to kFinishDownloadUrl |
| + // to finish all pending requests. It is never sent, so the following URL |
| + // blocks indefinitely, which is good because the request stays alive and the |
| + // test can try to reuse the request id without a race. |
| + const char* blocking_url = net::URLRequestSlowDownloadJob::kUnknownSizeUrl; |
| + ResourceHostMsg_Request request(CreateXHRRequest(blocking_url)); |
| + |
| + RenderProcessHostWatcher web_process_killed( |
| + web_rfh->GetProcess(), |
| + RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| + // Use the same request id twice. |
|
Charlie Reis
2016/01/28 22:05:16
nit: Move comment above the RenderProcessHostWatch
gzobqq
2016/01/30 07:18:58
Done.
|
| + IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| + web_rfh->GetProcess()->GetChannel(), |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, request)); |
| + IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| + web_rfh->GetProcess()->GetChannel(), |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, request)); |
| + web_process_killed.Wait(); |
| +} |
| + |
| } // namespace |
| @@ -145,6 +190,12 @@ class SecurityExploitBrowserTest : public ContentBrowserTest { |
| ",EXCLUDE localhost"); |
| } |
| + void SetUpOnMainThread() override { |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, FROM_HERE, |
| + base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler)); |
| + } |
| + |
| protected: |
| // Tests that a given file path sent in a ViewHostMsg_RunFileChooser will |
| // cause renderer to be killed. |
| @@ -384,7 +435,8 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) { |
| RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| web_rfh->GetProcess()->GetChannel(), |
| - ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, |
| chrome_origin_msg)); |
| web_process_killed.Wait(); |
| } |
| @@ -404,7 +456,8 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) { |
| RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| web_rfh->GetProcess()->GetChannel(), |
| - ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, |
| embedder_isolated_origin_msg)); |
| web_process_killed.Wait(); |
| SetBrowserClientForTesting(old_client); |
| @@ -418,7 +471,8 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) { |
| RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| web_rfh->GetProcess()->GetChannel(), |
| - ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, |
| invalid_origin_msg)); |
| web_process_killed.Wait(); |
| } |
| @@ -431,10 +485,20 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) { |
| RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| IPC::IpcSecurityTestUtil::PwnMessageReceived( |
| web_rfh->GetProcess()->GetChannel(), |
| - ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), 1, |
| + ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(), |
| + kRequestIdNotPreviouslyUsed, |
| invalid_scheme_origin_msg)); |
| web_process_killed.Wait(); |
| } |
| } |
| +// Renderer process should not be able to create multiple requests with the same |
| +// id. |
| +IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) { |
| + // Existing loader in pending_loaders_. |
| + TryCreateDuplicateRequestIds(shell(), false); |
| + // Existing loader in blocked_loaders_map_. |
| + TryCreateDuplicateRequestIds(shell(), true); |
| +} |
| + |
| } // namespace content |