Index: content/browser/renderer_host/render_view_host_impl.cc |
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc |
index 8424da94d3255969f6fa9e015b0b8424ea5d5856..d3363f535cca660b88fe45b126d835e29fe85148 100644 |
--- a/content/browser/renderer_host/render_view_host_impl.cc |
+++ b/content/browser/renderer_host/render_view_host_impl.cc |
@@ -67,6 +67,7 @@ |
#include "ui/shell_dialogs/selected_file_info.h" |
#include "ui/snapshot/snapshot.h" |
#include "webkit/fileapi/isolated_context.h" |
+#include "webkit/glue/glue_serialize.h" |
#include "webkit/glue/webdropdata.h" |
#include "webkit/glue/webkit_glue.h" |
@@ -1224,11 +1225,25 @@ void RenderViewHostImpl::OnNavigate(const IPC::Message& msg) { |
FilterURL(policy, process, true, &validated_params.password_form.origin); |
FilterURL(policy, process, true, &validated_params.password_form.action); |
+ // Without this check, the renderer can trick the browser into using |
+ // filenames it can't access in a future session restore. |
+ if (!CanAccessFilesOfSerializedState(validated_params.content_state)) { |
+ GetProcess()->ReceivedBadMessage(); |
+ return; |
+ } |
+ |
delegate_->DidNavigate(this, validated_params); |
} |
void RenderViewHostImpl::OnUpdateState(int32 page_id, |
const std::string& state) { |
+ // Without this check, the renderer can trick the browser into using |
+ // filenames it can't access in a future session restore. |
+ if (!CanAccessFilesOfSerializedState(state)) { |
+ GetProcess()->ReceivedBadMessage(); |
+ return; |
+ } |
+ |
delegate_->UpdateState(this, page_id, state); |
} |
@@ -2042,4 +2057,18 @@ void RenderViewHostImpl::ClearPowerSaveBlockers() { |
STLDeleteValues(&power_save_blockers_); |
} |
+bool RenderViewHostImpl::CanAccessFilesOfSerializedState( |
+ const std::string& state) const { |
+ ChildProcessSecurityPolicyImpl* policy = |
+ ChildProcessSecurityPolicyImpl::GetInstance(); |
+ const std::vector<base::FilePath>& file_paths = |
+ webkit_glue::FilePathsFromHistoryState(state); |
+ for (std::vector<base::FilePath>::const_iterator file = file_paths.begin(); |
+ file != file_paths.end(); ++file) { |
+ if (!policy->CanReadFile(GetProcess()->GetID(), *file)) |
+ return false; |
+ } |
+ return true; |
+} |
+ |
} // namespace content |