Index: webkit/fileapi/file_system_directory_database.cc |
=================================================================== |
--- webkit/fileapi/file_system_directory_database.cc (revision 171066) |
+++ webkit/fileapi/file_system_directory_database.cc (working copy) |
@@ -369,6 +369,27 @@ |
num_hierarchy_links_in_db_ == visited_links; |
} |
+// Returns true if the given |data_path| contains no parent references ("..") |
+// and does not refer to special system files. |
+// This is called in GetFileInfo, AddFileInfo and UpdateFileInfo to |
+// ensure we're only dealing with valid data paths. |
+bool VerifyDataPath(const FilePath& data_path) { |
+ // |data_path| should not contain any ".." and should be a relative path |
+ // (to the filesystem_data_directory_). |
+ if (data_path.ReferencesParent() || data_path.IsAbsolute()) |
+ return false; |
+ // See if it's not pointing to the special system paths. |
+ const FilePath kExcludes[] = { |
+ FilePath(kDirectoryDatabaseName), |
+ FilePath(fileapi::FileSystemUsageCache::kUsageFileName), |
+ }; |
+ for (size_t i = 0; i < arraysize(kExcludes); ++i) { |
+ if (data_path == kExcludes[i] || kExcludes[i].IsParent(data_path)) |
+ return false; |
+ } |
+ return true; |
+} |
+ |
} // namespace |
namespace fileapi { |
@@ -461,8 +482,16 @@ |
leveldb::Status status = |
db_->Get(leveldb::ReadOptions(), file_key, &file_data_string); |
if (status.ok()) { |
- return FileInfoFromPickle( |
+ bool success = FileInfoFromPickle( |
Pickle(file_data_string.data(), file_data_string.length()), info); |
+ if (!success) |
+ return false; |
+ if (!VerifyDataPath(info->data_path)) { |
+ LOG(ERROR) << "Resolved data path is invalid: " |
+ << info->data_path.value(); |
+ return false; |
+ } |
+ return true; |
} |
// Special-case the root, for databases that haven't been initialized yet. |
// Without this, a query for the root's file info, made before creating the |
@@ -821,6 +850,10 @@ |
// This does very few safety checks! |
bool FileSystemDirectoryDatabase::AddFileInfoHelper( |
const FileInfo& info, FileId file_id, leveldb::WriteBatch* batch) { |
+ if (!VerifyDataPath(info.data_path)) { |
+ LOG(ERROR) << "Invalid data path is given: " << info.data_path.value(); |
+ return false; |
+ } |
std::string id_string = GetFileLookupKey(file_id); |
if (!file_id) { |
// The root directory doesn't need to be looked up by path from its parent. |