OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/render_frame_host_impl.h" | 5 #include "content/browser/frame_host/render_frame_host_impl.h" |
6 | 6 |
7 #include "base/containers/hash_tables.h" | 7 #include "base/containers/hash_tables.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/metrics/user_metrics_action.h" | |
9 #include "content/browser/frame_host/cross_process_frame_connector.h" | 10 #include "content/browser/frame_host/cross_process_frame_connector.h" |
10 #include "content/browser/frame_host/frame_tree.h" | 11 #include "content/browser/frame_host/frame_tree.h" |
11 #include "content/browser/frame_host/frame_tree_node.h" | 12 #include "content/browser/frame_host/frame_tree_node.h" |
12 #include "content/browser/frame_host/navigator.h" | 13 #include "content/browser/frame_host/navigator.h" |
13 #include "content/browser/frame_host/render_frame_host_delegate.h" | 14 #include "content/browser/frame_host/render_frame_host_delegate.h" |
14 #include "content/browser/renderer_host/render_view_host_impl.h" | 15 #include "content/browser/renderer_host/render_view_host_impl.h" |
15 #include "content/common/frame_messages.h" | 16 #include "content/common/frame_messages.h" |
16 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
17 #include "content/public/browser/render_process_host.h" | 18 #include "content/public/browser/render_process_host.h" |
18 #include "content/public/browser/render_widget_host_view.h" | 19 #include "content/public/browser/render_widget_host_view.h" |
19 #include "content/public/browser/user_metrics.h" | 20 #include "content/public/browser/user_metrics.h" |
21 #include "content/public/common/url_constants.h" | |
20 #include "url/gurl.h" | 22 #include "url/gurl.h" |
21 | 23 |
22 namespace content { | 24 namespace content { |
23 | 25 |
24 // The (process id, routing id) pair that identifies one RenderFrame. | 26 // The (process id, routing id) pair that identifies one RenderFrame. |
25 typedef std::pair<int32, int32> RenderFrameHostID; | 27 typedef std::pair<int32, int32> RenderFrameHostID; |
26 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> | 28 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> |
27 RoutingIDFrameMap; | 29 RoutingIDFrameMap; |
28 static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = | 30 static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = |
29 LAZY_INSTANCE_INITIALIZER; | 31 LAZY_INSTANCE_INITIALIZER; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 bool handled = true; | 128 bool handled = true; |
127 bool msg_is_ok = true; | 129 bool msg_is_ok = true; |
128 IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok) | 130 IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok) |
129 IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach) | 131 IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach) |
130 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame, | 132 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame, |
131 OnDidStartProvisionalLoadForFrame) | 133 OnDidStartProvisionalLoadForFrame) |
132 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError, | 134 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError, |
133 OnDidFailProvisionalLoadWithError) | 135 OnDidFailProvisionalLoadWithError) |
134 IPC_MESSAGE_HANDLER(FrameHostMsg_DidRedirectProvisionalLoad, | 136 IPC_MESSAGE_HANDLER(FrameHostMsg_DidRedirectProvisionalLoad, |
135 OnDidRedirectProvisionalLoad) | 137 OnDidRedirectProvisionalLoad) |
138 IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad, | |
139 OnNavigate(msg)) | |
136 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) | 140 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) |
137 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) | 141 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) |
138 IPC_END_MESSAGE_MAP_EX() | 142 IPC_END_MESSAGE_MAP_EX() |
139 | 143 |
140 if (!msg_is_ok) { | 144 if (!msg_is_ok) { |
141 // The message had a handler, but its de-serialization failed. | 145 // The message had a handler, but its de-serialization failed. |
142 // Kill the renderer. | 146 // Kill the renderer. |
143 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH")); | 147 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH")); |
144 GetProcess()->ReceivedBadMessage(); | 148 GetProcess()->ReceivedBadMessage(); |
145 } | 149 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 } | 184 } |
181 | 185 |
182 void RenderFrameHostImpl::OnDidRedirectProvisionalLoad( | 186 void RenderFrameHostImpl::OnDidRedirectProvisionalLoad( |
183 int32 page_id, | 187 int32 page_id, |
184 const GURL& source_url, | 188 const GURL& source_url, |
185 const GURL& target_url) { | 189 const GURL& target_url) { |
186 frame_tree_node_->navigator()->DidRedirectProvisionalLoad( | 190 frame_tree_node_->navigator()->DidRedirectProvisionalLoad( |
187 this, page_id, source_url, target_url); | 191 this, page_id, source_url, target_url); |
188 } | 192 } |
189 | 193 |
194 // Called when the renderer navigates. For every frame loaded, we'll get this | |
195 // notification containing parameters identifying the navigation. | |
196 // | |
197 // Subframes are identified by the page transition type. For subframes loaded | |
198 // as part of a wider page load, the page_id will be the same as for the top | |
199 // level frame. If the user explicitly requests a subframe navigation, we will | |
200 // get a new page_id because we need to create a new navigation entry for that | |
201 // action. | |
202 void RenderFrameHostImpl::OnNavigate(const IPC::Message& msg) { | |
203 // Read the parameters out of the IPC message directly to avoid making another | |
204 // copy when we filter the URLs. | |
205 PickleIterator iter(msg); | |
206 FrameHostMsg_DidCommitProvisionalLoad_Params validated_params; | |
207 if (!IPC::ParamTraits<FrameHostMsg_DidCommitProvisionalLoad_Params>:: | |
208 Read(&msg, &iter, &validated_params)) | |
209 return; | |
210 | |
211 // If we're waiting for a cross-site beforeunload ack from this renderer and | |
212 // we receive a Navigate message from the main frame, then the renderer was | |
213 // navigating already and sent it before hearing the ViewMsg_Stop message. | |
214 // We do not want to cancel the pending navigation in this case, since the | |
215 // old page will soon be stopped. Instead, treat this as a beforeunload ack | |
216 // to allow the pending navigation to continue. | |
217 if (render_view_host_->is_waiting_for_beforeunload_ack_ && | |
218 render_view_host_->unload_ack_is_for_cross_site_transition_ && | |
219 PageTransitionIsMainFrame(validated_params.transition)) { | |
220 render_view_host_->OnShouldCloseACK( | |
221 true, render_view_host_->send_should_close_start_time_, | |
222 base::TimeTicks::Now()); | |
223 return; | |
224 } | |
225 | |
226 // If we're waiting for an unload ack from this renderer and we receive a | |
227 // Navigate message, then the renderer was navigating before it received the | |
228 // unload request. It will either respond to the unload request soon or our | |
229 // timer will expire. Either way, we should ignore this message, because we | |
230 // have already committed to closing this renderer. | |
231 if (render_view_host_->is_waiting_for_unload_ack_) | |
232 return; | |
233 | |
234 // Cache the main frame id, so we can use it for creating the frame tree | |
235 // root node when needed. | |
236 if (PageTransitionIsMainFrame(validated_params.transition)) { | |
237 if (render_view_host_->main_frame_id_ == -1) { | |
238 render_view_host_->main_frame_id_ = validated_params.frame_id; | |
239 } else { | |
240 // TODO(nasko): We plan to remove the usage of frame_id in navigation | |
241 // and move to routing ids. This is in place to ensure that a | |
242 // renderer is not misbehaving and sending us incorrect data. | |
243 DCHECK_EQ(render_view_host_->main_frame_id_, validated_params.frame_id); | |
244 } | |
245 } | |
246 RenderProcessHost* process = GetProcess(); | |
247 | |
248 // Attempts to commit certain off-limits URL should be caught more strictly | |
249 // than our FilterURL checks below. If a renderer violates this policy, it | |
250 // should be killed. | |
251 if (!render_view_host_->CanCommitURL(validated_params.url)) { | |
Charlie Reis
2014/02/05 23:30:37
Let's move CanCommitURL to RFH rather than calling
nasko
2014/02/06 01:55:13
Done.
| |
252 VLOG(1) << "Blocked URL " << validated_params.url.spec(); | |
253 validated_params.url = GURL(kAboutBlankURL); | |
254 RecordAction(base::UserMetricsAction("CanCommitURL_BlockedAndKilled")); | |
255 // Kills the process. | |
256 process->ReceivedBadMessage(); | |
257 } | |
258 | |
259 // Now that something has committed, we don't need to track whether the | |
260 // initial page has been accessed. | |
261 render_view_host_->has_accessed_initial_document_ = false; | |
262 | |
263 // Without this check, an evil renderer can trick the browser into creating | |
264 // a navigation entry for a banned URL. If the user clicks the back button | |
265 // followed by the forward button (or clicks reload, or round-trips through | |
266 // session restore, etc), we'll think that the browser commanded the | |
267 // renderer to load the URL and grant the renderer the privileges to request | |
268 // the URL. To prevent this attack, we block the renderer from inserting | |
269 // banned URLs into the navigation controller in the first place. | |
270 process->FilterURL(false, &validated_params.url); | |
271 process->FilterURL(true, &validated_params.referrer.url); | |
272 for (std::vector<GURL>::iterator it(validated_params.redirects.begin()); | |
273 it != validated_params.redirects.end(); ++it) { | |
274 process->FilterURL(false, &(*it)); | |
275 } | |
276 process->FilterURL(true, &validated_params.searchable_form_url); | |
277 | |
278 // Without this check, the renderer can trick the browser into using | |
279 // filenames it can't access in a future session restore. | |
280 if (!render_view_host_->CanAccessFilesOfPageState( | |
281 validated_params.page_state)) { | |
282 GetProcess()->ReceivedBadMessage(); | |
283 return; | |
284 } | |
285 | |
286 frame_tree_node()->navigator()->DidNavigate(this, validated_params); | |
287 } | |
288 | |
190 void RenderFrameHostImpl::SwapOut() { | 289 void RenderFrameHostImpl::SwapOut() { |
191 if (render_view_host_->IsRenderViewLive()) { | 290 if (render_view_host_->IsRenderViewLive()) { |
192 Send(new FrameMsg_SwapOut(routing_id_)); | 291 Send(new FrameMsg_SwapOut(routing_id_)); |
193 } else { | 292 } else { |
194 // Our RenderViewHost doesn't have a live renderer, so just skip the unload | 293 // Our RenderViewHost doesn't have a live renderer, so just skip the unload |
195 // event. | 294 // event. |
196 OnSwappedOut(true); | 295 OnSwappedOut(true); |
197 } | 296 } |
198 } | 297 } |
199 | 298 |
(...skipping 15 matching lines...) Expand all Loading... | |
215 // when users want to copy the original link URL. | 314 // when users want to copy the original link URL. |
216 process->FilterURL(true, &validated_params.link_url); | 315 process->FilterURL(true, &validated_params.link_url); |
217 process->FilterURL(true, &validated_params.src_url); | 316 process->FilterURL(true, &validated_params.src_url); |
218 process->FilterURL(false, &validated_params.page_url); | 317 process->FilterURL(false, &validated_params.page_url); |
219 process->FilterURL(true, &validated_params.frame_url); | 318 process->FilterURL(true, &validated_params.frame_url); |
220 | 319 |
221 delegate_->ShowContextMenu(this, validated_params); | 320 delegate_->ShowContextMenu(this, validated_params); |
222 } | 321 } |
223 | 322 |
224 } // namespace content | 323 } // namespace content |
OLD | NEW |