Commit 642bac85 authored by Anand K. Mistry's avatar Anand K. Mistry Committed by Commit Bot

Add sanitisation for FSP ReadDirectory() results.

Filter out invalid entries in a provided filesystem's ReadDirectory()
results list. Entries are expected to have a valid type and a name that
does not contain certain invalid characters.

Bug: 992321
Change-Id: Ie7e3b47da349892537643cba239d7f88ed4f60ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1888867Reviewed-by: default avatarNaoki Fukino <fukino@chromium.org>
Commit-Queue: Anand Mistry <amistry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712036}
parent 646c758f
...@@ -25,6 +25,13 @@ const size_t kFakeFileSize = sizeof(kFakeFileText) - 1u; ...@@ -25,6 +25,13 @@ const size_t kFakeFileSize = sizeof(kFakeFileText) - 1u;
const char kFakeFileModificationTime[] = "Fri Apr 25 01:47:53 UTC 2014"; const char kFakeFileModificationTime[] = "Fri Apr 25 01:47:53 UTC 2014";
const char kFakeFileMimeType[] = "text/plain"; const char kFakeFileMimeType[] = "text/plain";
constexpr base::FilePath::CharType kBadFakeEntryPath1[] =
FILE_PATH_LITERAL("/bad1");
constexpr char kBadFakeEntryName1[] = "/bad1";
constexpr base::FilePath::CharType kBadFakeEntryPath2[] =
FILE_PATH_LITERAL("/bad2");
constexpr char kBadFakeEntryName2[] = "bad2";
} // namespace } // namespace
const base::FilePath::CharType kFakeFilePath[] = const base::FilePath::CharType kFakeFilePath[] =
...@@ -50,6 +57,13 @@ FakeProvidedFileSystem::FakeProvidedFileSystem( ...@@ -50,6 +57,13 @@ FakeProvidedFileSystem::FakeProvidedFileSystem(
DCHECK(base::Time::FromString(kFakeFileModificationTime, &modification_time)); DCHECK(base::Time::FromString(kFakeFileModificationTime, &modification_time));
AddEntry(base::FilePath(kFakeFilePath), false, kFakeFileName, kFakeFileSize, AddEntry(base::FilePath(kFakeFilePath), false, kFakeFileName, kFakeFileSize,
modification_time, kFakeFileMimeType, kFakeFileText); modification_time, kFakeFileMimeType, kFakeFileText);
// Add a set of bad entries, in the root directory, which should be filtered
// out.
AddEntry(base::FilePath(kBadFakeEntryPath1), false, kBadFakeEntryName1,
kFakeFileSize, modification_time, kFakeFileMimeType, kFakeFileText);
AddEntry(base::FilePath(kBadFakeEntryPath2), false, kBadFakeEntryName2,
kFakeFileSize, modification_time, kFakeFileMimeType, kFakeFileText);
} }
FakeProvidedFileSystem::~FakeProvidedFileSystem() {} FakeProvidedFileSystem::~FakeProvidedFileSystem() {}
...@@ -156,11 +170,13 @@ AbortCallback FakeProvidedFileSystem::ReadDirectory( ...@@ -156,11 +170,13 @@ AbortCallback FakeProvidedFileSystem::ReadDirectory(
const base::FilePath file_path = it->first; const base::FilePath file_path = it->first;
if (file_path == directory_path || directory_path.IsParent(file_path)) { if (file_path == directory_path || directory_path.IsParent(file_path)) {
const EntryMetadata* const metadata = it->second->metadata.get(); const EntryMetadata* const metadata = it->second->metadata.get();
entry_list.emplace_back( filesystem::mojom::FsFileType entry_type =
base::FilePath(*metadata->name), *metadata->is_directory ? filesystem::mojom::FsFileType::DIRECTORY
*metadata->is_directory : filesystem::mojom::FsFileType::REGULAR_FILE;
? filesystem::mojom::FsFileType::DIRECTORY if (*metadata->name == kBadFakeEntryName2) {
: filesystem::mojom::FsFileType::REGULAR_FILE); entry_type = static_cast<filesystem::mojom::FsFileType>(7);
}
entry_list.emplace_back(base::FilePath(*metadata->name), entry_type);
} }
} }
......
...@@ -4,12 +4,15 @@ ...@@ -4,12 +4,15 @@
#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h" #include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
#include <algorithm>
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h" #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
...@@ -108,6 +111,23 @@ void OnReadDirectory(storage::AsyncFileUtil::ReadDirectoryCallback callback, ...@@ -108,6 +111,23 @@ void OnReadDirectory(storage::AsyncFileUtil::ReadDirectoryCallback callback,
base::File::Error result, base::File::Error result,
storage::AsyncFileUtil::EntryList entry_list, storage::AsyncFileUtil::EntryList entry_list,
bool has_more) { bool has_more) {
auto new_end_it =
std::remove_if(entry_list.begin(), entry_list.end(),
[](const filesystem::mojom::DirectoryEntry& entry) {
if (!filesystem::mojom::IsKnownEnumValue(entry.type)) {
return true;
}
if (entry.name.empty() || entry.name.value() == "." ||
entry.name.value() == ".." ||
base::Contains(entry.name.value(), '\0') ||
base::Contains(entry.name.value(), '/') ||
base::Contains(entry.name.value(), '\\')) {
return true;
}
return false;
});
entry_list.erase(new_end_it, entry_list.end());
base::PostTask( base::PostTask(
FROM_HERE, {BrowserThread::IO}, FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, result, std::move(entry_list), has_more)); base::BindOnce(callback, result, std::move(entry_list), has_more));
......
...@@ -74,6 +74,7 @@ class EventLogger { ...@@ -74,6 +74,7 @@ class EventLogger {
storage::AsyncFileUtil::EntryList file_list, storage::AsyncFileUtil::EntryList file_list,
bool has_more) { bool has_more) {
result_.reset(new base::File::Error(error)); result_.reset(new base::File::Error(error));
read_directory_list_ = std::move(file_list);
} }
void OnCreateSnapshotFile( void OnCreateSnapshotFile(
...@@ -88,8 +89,13 @@ class EventLogger { ...@@ -88,8 +89,13 @@ class EventLogger {
base::File::Error* result() { return result_.get(); } base::File::Error* result() { return result_.get(); }
const storage::AsyncFileUtil::EntryList& read_directory_list() {
return read_directory_list_;
}
private: private:
std::unique_ptr<base::File::Error> result_; std::unique_ptr<base::File::Error> result_;
storage::AsyncFileUtil::EntryList read_directory_list_;
DISALLOW_COPY_AND_ASSIGN(EventLogger); DISALLOW_COPY_AND_ASSIGN(EventLogger);
}; };
...@@ -289,6 +295,22 @@ TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) { ...@@ -289,6 +295,22 @@ TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) {
EXPECT_EQ(base::File::FILE_OK, *logger.result()); EXPECT_EQ(base::File::FILE_OK, *logger.result());
} }
TEST_F(FileSystemProviderProviderAsyncFileUtilTest,
ReadDirectory_SanitiseResultsList) {
EventLogger logger;
async_file_util_->ReadDirectory(
CreateOperationContext(), root_url_,
base::Bind(&EventLogger::OnReadDirectory, base::Unretained(&logger)));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(logger.result());
EXPECT_EQ(base::File::FILE_OK, *logger.result());
EXPECT_EQ(1U, logger.read_directory_list().size());
EXPECT_EQ(base::FilePath(kFakeFilePath + 1 /* No leading slash. */),
logger.read_directory_list()[0].name);
}
TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) { TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) {
EventLogger logger; EventLogger logger;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment