summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 20:59:39 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-06 20:59:39 +0000
commit8df448286e59828542c9ef0234a6fb49909d95dc (patch)
tree4d08f71b35e2109be496569854a5cb7b6ce72563
parentfadf1b91df3e2d36c49a371e8f06b934b368e891 (diff)
downloadchromium_src-8df448286e59828542c9ef0234a6fb49909d95dc.zip
chromium_src-8df448286e59828542c9ef0234a6fb49909d95dc.tar.gz
chromium_src-8df448286e59828542c9ef0234a6fb49909d95dc.tar.bz2
Add a way to be notified when a deletable file reference is destroyed so that
callers can clean up any other state associated with it. I used this capability to revoke the renderer's permissions for a downloaded file. The old code path where it would revoke the permissions as soon as the download was complete (as indicated by the renderer) doesn't account for the case where the file is stored in a blob and that file reference outlives the resource request. BUG=81319 TEST=PPAPI.URLLoader Review URL: http://codereview.chromium.org/6930042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84500 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/resource_dispatcher_host.cc24
-rw-r--r--webkit/blob/deletable_file_reference.cc10
-rw-r--r--webkit/blob/deletable_file_reference.h9
3 files changed, 40 insertions, 3 deletions
diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc
index 4b30e97..e29a625 100644
--- a/content/browser/renderer_host/resource_dispatcher_host.cc
+++ b/content/browser/renderer_host/resource_dispatcher_host.cc
@@ -9,6 +9,7 @@
#include <set>
#include <vector>
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -218,6 +219,12 @@ std::vector<int> GetAllNetErrorCodes() {
return all_error_codes;
}
+void RemoveDownloadFileFromChildSecurityPolicy(int child_id,
+ const FilePath& path) {
+ ChildProcessSecurityPolicy::GetInstance()->RevokeAllPermissionsForFile(
+ child_id, path);
+}
+
#if defined(OS_WIN)
#pragma warning(disable: 4748)
#pragma optimize("", off)
@@ -625,6 +632,18 @@ void ResourceDispatcherHost::RegisterDownloadedTempFile(
registered_temp_files_[child_id][request_id] = reference;
ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(
child_id, reference->path());
+
+ // When the temp file is deleted, revoke permissions that the renderer has
+ // to that file. This covers an edge case where the file is deleted and then
+ // the same name is re-used for some other purpose, we don't want the old
+ // renderer to still have access to it.
+ //
+ // We do this when the file is deleted because the renderer can take a blob
+ // reference to the temp file that outlives the url loaded that it was
+ // loaded with to keep the file (and permissions) alive.
+ reference->AddDeletionCallback(
+ base::Bind(&RemoveDownloadFileFromChildSecurityPolicy,
+ child_id));
}
void ResourceDispatcherHost::UnregisterDownloadedTempFile(
@@ -634,9 +653,10 @@ void ResourceDispatcherHost::UnregisterDownloadedTempFile(
if (found == map.end())
return;
- ChildProcessSecurityPolicy::GetInstance()->RevokeAllPermissionsForFile(
- child_id, found->second->path());
map.erase(found);
+
+ // Note that we don't remove the security bits here. This will be done
+ // when all file refs are deleted (see RegisterDownloadedTempFile).
}
bool ResourceDispatcherHost::Send(IPC::Message* message) {
diff --git a/webkit/blob/deletable_file_reference.cc b/webkit/blob/deletable_file_reference.cc
index 3f2daed..a47013d 100644
--- a/webkit/blob/deletable_file_reference.cc
+++ b/webkit/blob/deletable_file_reference.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -55,6 +55,11 @@ scoped_refptr<DeletableFileReference> DeletableFileReference::GetOrCreate(
return reference;
}
+void DeletableFileReference::AddDeletionCallback(
+ const DeletionCallback& callback) {
+ deletion_callbacks_.push_back(callback);
+}
+
DeletableFileReference::DeletableFileReference(
const FilePath& path, base::MessageLoopProxy* file_thread)
: path_(path), file_thread_(file_thread) {
@@ -62,6 +67,9 @@ DeletableFileReference::DeletableFileReference(
}
DeletableFileReference::~DeletableFileReference() {
+ for (size_t i = 0; i < deletion_callbacks_.size(); i++)
+ deletion_callbacks_[i].Run(path_);
+
DCHECK(g_deletable_file_map.Get().find(path_)->second == this);
g_deletable_file_map.Get().erase(path_);
base::FileUtilProxy::Delete(file_thread_, path_, false /* recursive */, NULL);
diff --git a/webkit/blob/deletable_file_reference.h b/webkit/blob/deletable_file_reference.h
index b432bf0c..a4301bf 100644
--- a/webkit/blob/deletable_file_reference.h
+++ b/webkit/blob/deletable_file_reference.h
@@ -6,6 +6,9 @@
#define WEBKIT_BLOB_DELETABLE_FILE_REFERENCE_H_
#pragma once
+#include <vector>
+
+#include "base/callback.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
@@ -19,6 +22,8 @@ namespace webkit_blob {
// to be deleted upon final release.
class DeletableFileReference : public base::RefCounted<DeletableFileReference> {
public:
+ typedef base::Callback<void(const FilePath&)> DeletionCallback;
+
// Returns a DeletableFileReference for the given path, if no reference
// for this path exists returns NULL.
static scoped_refptr<DeletableFileReference> Get(const FilePath& path);
@@ -31,6 +36,8 @@ class DeletableFileReference : public base::RefCounted<DeletableFileReference> {
// The full file path.
const FilePath& path() const { return path_; }
+ void AddDeletionCallback(const DeletionCallback& callback);
+
private:
friend class base::RefCounted<DeletableFileReference>;
@@ -41,6 +48,8 @@ class DeletableFileReference : public base::RefCounted<DeletableFileReference> {
const FilePath path_;
scoped_refptr<base::MessageLoopProxy> file_thread_;
+ std::vector<DeletionCallback> deletion_callbacks_;
+
DISALLOW_COPY_AND_ASSIGN(DeletableFileReference);
};