Index: content/browser/fileapi/browser_file_system_helper.cc |
diff --git a/content/browser/fileapi/browser_file_system_helper.cc b/content/browser/fileapi/browser_file_system_helper.cc |
index e7b22c58204568cc034e4a14a87e664c475a692e..5db3ff97feed75a3444f029cf4644a3f27937a20 100644 |
--- a/content/browser/fileapi/browser_file_system_helper.cc |
+++ b/content/browser/fileapi/browser_file_system_helper.cc |
@@ -10,11 +10,15 @@ |
#include "base/command_line.h" |
#include "base/files/file_path.h" |
#include "base/threading/sequenced_worker_pool.h" |
+#include "content/browser/child_process_security_policy_impl.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/common/content_switches.h" |
#include "webkit/fileapi/external_mount_points.h" |
+#include "webkit/fileapi/file_permission_policy.h" |
#include "webkit/fileapi/file_system_options.h" |
#include "webkit/fileapi/file_system_task_runners.h" |
+#include "webkit/fileapi/local_file_system_operation.h" |
+#include "webkit/fileapi/sandbox_mount_point_provider.h" |
#include "webkit/quota/quota_manager.h" |
namespace content { |
@@ -65,4 +69,97 @@ scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext( |
CreateBrowserFileSystemOptions(is_incognito)); |
} |
+bool CheckFileSystemPermissionsForProcess( |
+ fileapi::FileSystemContext* context, int process_id, |
+ const fileapi::FileSystemURL& url, int permissions, |
+ base::PlatformFileError* error) { |
+ DCHECK(error); |
+ *error = base::PLATFORM_FILE_OK; |
+ |
+ if (!url.is_valid()) { |
+ *error = base::PLATFORM_FILE_ERROR_INVALID_URL; |
+ return false; |
+ } |
+ |
+ fileapi::FileSystemMountPointProvider* mount_point_provider = |
+ context->GetMountPointProvider(url.type()); |
+ if (!mount_point_provider) { |
+ *error = base::PLATFORM_FILE_ERROR_INVALID_URL; |
+ return false; |
+ } |
+ |
+ base::FilePath file_path; |
+ ChildProcessSecurityPolicyImpl* policy = |
+ ChildProcessSecurityPolicyImpl::GetInstance(); |
+ |
+ switch (mount_point_provider->GetPermissionPolicy(url, permissions)) { |
+ case fileapi::FILE_PERMISSION_ALWAYS_DENY: |
+ *error = base::PLATFORM_FILE_ERROR_SECURITY; |
+ return false; |
+ case fileapi::FILE_PERMISSION_ALWAYS_ALLOW: |
+ CHECK(mount_point_provider == context->sandbox_provider()); |
+ return true; |
+ case fileapi::FILE_PERMISSION_USE_FILE_PERMISSION: { |
+ const bool success = policy->HasPermissionsForFile( |
+ process_id, url.path(), permissions); |
+ if (!success) |
+ *error = base::PLATFORM_FILE_ERROR_SECURITY; |
+ return success; |
+ } |
+ case fileapi::FILE_PERMISSION_USE_FILESYSTEM_PERMISSION: { |
+ const bool success = policy->HasPermissionsForFileSystem( |
+ process_id, url.filesystem_id(), permissions); |
+ if (!success) |
+ *error = base::PLATFORM_FILE_ERROR_SECURITY; |
+ return success; |
+ } |
+ } |
+ NOTREACHED(); |
+ *error = base::PLATFORM_FILE_ERROR_SECURITY; |
+ return false; |
+} |
+ |
+void SyncGetPlatformPath(fileapi::FileSystemContext* context, |
+ int process_id, |
+ const GURL& path, |
+ base::FilePath* platform_path) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ DCHECK(platform_path); |
+ *platform_path = base::FilePath(); |
+ fileapi::FileSystemURL url(context->CrackURL(path)); |
+ if (!url.is_valid()) |
+ return; |
+ |
+ // Make sure if this file is ok to be read (in the current architecture |
+ // which means roughly same as the renderer is allowed to get the platform |
+ // path to the file). |
+ base::PlatformFileError error; |
+ if (!CheckFileSystemPermissionsForProcess( |
+ context, process_id, url, fileapi::kReadFilePermissions, &error)) |
+ return; |
+ |
+ // This is called only by pepper plugin as of writing to get the |
+ // underlying platform path to upload a file in the sandboxed filesystem |
+ // (e.g. TEMPORARY or PERSISTENT). |
+ // TODO(kinuko): this hack should go away once appropriate upload-stream |
+ // handling based on element types is supported. |
+ fileapi::LocalFileSystemOperation* operation = |
+ context->CreateFileSystemOperation( |
+ url, NULL)->AsLocalFileSystemOperation(); |
+ DCHECK(operation); |
+ if (!operation) |
+ return; |
+ |
+ operation->SyncGetPlatformPath(url, platform_path); |
+ |
+ // The path is to be attached to URLLoader so we grant read permission |
+ // for the file. (We first need to check if it can already be read not to |
+ // overwrite existing permissions) |
+ if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile( |
+ process_id, *platform_path)) { |
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( |
+ process_id, *platform_path); |
+ } |
+} |
+ |
} // namespace content |