summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/file_util.h3
-rw-r--r--base/file_util_posix.cc15
-rw-r--r--base/file_util_win.cc6
-rw-r--r--webkit/fileapi/file_system_file_util.cc12
4 files changed, 35 insertions, 1 deletions
diff --git a/base/file_util.h b/base/file_util.h
index 28c96e9..d9f4c3e 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -328,6 +328,9 @@ BASE_API bool NormalizeToNativeFilePath(const FilePath& path,
FilePath* nt_path);
#endif
+// This function will return if the given file is a symlink or not.
+BASE_API bool IsLink(const FilePath& file_path);
+
// Returns information about the given file path.
BASE_API bool GetFileInfo(const FilePath& file_path,
base::PlatformFileInfo* info);
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 28d6a61..89487d4 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -522,6 +522,21 @@ bool CreateDirectory(const FilePath& full_path) {
return true;
}
+// TODO(rkc): Refactor GetFileInfo and FileEnumerator to handle symlinks
+// correctly. http://code.google.com/p/chromium-os/issues/detail?id=15948
+bool IsLink(const FilePath& file_path) {
+ struct stat st;
+ // If we can't lstat the file, it's safe to assume that the file won't at
+ // least be a 'followable' link.
+ if (lstat(file_path.value().c_str(), &st) != 0)
+ return false;
+
+ if (S_ISLNK(st.st_mode))
+ return true;
+ else
+ return false;
+}
+
bool GetFileInfo(const FilePath& file_path, base::PlatformFileInfo* results) {
stat_wrapper_t file_info;
if (CallStat(file_path.value().c_str(), &file_info) != 0)
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 3689614..93bfe1d 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -702,6 +702,12 @@ bool CreateDirectory(const FilePath& full_path) {
}
}
+// TODO(rkc): Work out if we want to handle NTFS junctions here or not, handle
+// them if we do decide to.
+bool IsLink(const FilePath& file_path) {
+ return false;
+}
+
bool GetFileInfo(const FilePath& file_path, base::PlatformFileInfo* results) {
base::ThreadRestrictions::AssertIOAllowed();
diff --git a/webkit/fileapi/file_system_file_util.cc b/webkit/fileapi/file_system_file_util.cc
index 3dfe459..5e5e973 100644
--- a/webkit/fileapi/file_system_file_util.cc
+++ b/webkit/fileapi/file_system_file_util.cc
@@ -95,6 +95,11 @@ PlatformFileError FileSystemFileUtil::GetFileInfo(
FilePath* platform_file_path) {
if (!file_util::PathExists(file_path))
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+ // TODO(rkc): Fix this hack once we have refactored file_util to handle
+ // symlinks correctly.
+ // http://code.google.com/p/chromium-os/issues/detail?id=15948
+ if (file_util::IsLink(file_path))
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
if (!file_util::GetFileInfo(file_path, file_info))
return base::PLATFORM_FILE_ERROR_FAILED;
*platform_file_path = file_path;
@@ -122,7 +127,12 @@ PlatformFileError FileSystemFileUtil::ReadDirectory(
// This will just give the entry's name instead of entire path
// if we use current.value().
entry.name = file_util::FileEnumerator::GetFilename(info).value();
- entries->push_back(entry);
+ // TODO(rkc): Fix this also once we've refactored file_util
+ // http://code.google.com/p/chromium-os/issues/detail?id=15948
+ // This currently just prevents a file from showing up at all
+ // if it's a link, hence preventing arbitary 'read' exploits.
+ if (!file_util::IsLink(file_path.Append(entry.name)))
+ entries->push_back(entry);
}
return base::PLATFORM_FILE_OK;
}