1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/net/chrome_network_delegate.h"
#include "base/base_paths.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ambient_time_of_day_constants.h"
#include "base/files/file_util.h"
#include "base/system/sys_info.h"
#include "chrome/common/chrome_paths.h"
#endif
#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "base/android/path_utils.h"
#endif
namespace {
bool g_access_to_all_files_enabled = false;
#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
// Returns true if |allowlist| contains |path| or a parent of |path|.
bool IsPathOnAllowlist(const base::FilePath& path,
const std::vector<base::FilePath>& allowlist) {
for (const auto& allowlisted_path : allowlist) {
// base::FilePath::operator== should probably handle trailing separators.
if (allowlisted_path == path.StripTrailingSeparators() ||
allowlisted_path.IsParent(path)) {
return true;
}
}
return false;
}
#endif
#if BUILDFLAG(IS_CHROMEOS)
// Returns true if access is allowed for |path| for a user with |profile_path).
bool IsAccessAllowedChromeOS(const base::FilePath& path,
const base::FilePath& profile_path) {
// Allow access to DriveFS logs. These reside in
// $PROFILE_PATH/GCache/v2/<opaque id>/Logs.
base::FilePath path_within_gcache_v2;
if (profile_path.Append("GCache/v2")
.AppendRelativePath(path, &path_within_gcache_v2)) {
std::vector<std::string> components = path_within_gcache_v2.GetComponents();
if (components.size() > 1 && components[1] == "Logs") {
return true;
}
}
// Use an allowlist to only allow access to files residing in the list of
// directories below.
static const base::FilePath::CharType* const kLocalAccessAllowList[] = {
"/home/chronos/user/MyFiles",
"/home/chronos/user/WebRTC Logs",
"/home/chronos/user/google-assistant-library/log",
"/home/chronos/user/log",
"/home/chronos/user/crostini.icons",
"/media",
"/opt/oem",
"/run/arc/sdcard/write/emulated/0",
"/usr/share/chromeos-assets",
"/var/log",
};
std::vector<base::FilePath> allowlist;
for (const auto* allowlisted_path : kLocalAccessAllowList)
allowlist.emplace_back(allowlisted_path);
base::FilePath temp_dir;
if (base::PathService::Get(base::DIR_TEMP, &temp_dir))
allowlist.push_back(temp_dir);
// The actual location of "/home/chronos/user/Xyz" is the Xyz directory under
// the profile path ("/home/chronos/user' is a hard link to current primary
// logged in profile.) For the support of multi-profile sessions, we are
// switching to use explicit "$PROFILE_PATH/Xyz" path and here allow such
// access.
if (!profile_path.empty()) {
allowlist.push_back(profile_path.AppendASCII("MyFiles"));
const base::FilePath webrtc_logs = profile_path.AppendASCII("WebRTC Logs");
allowlist.push_back(webrtc_logs);
}
// For developers using the linux-chromeos emulator, the MyFiles dir is at
// $HOME/Downloads. Ensure developers can access it for manual testing.
if (!base::SysInfo::IsRunningOnChromeOS()) {
base::FilePath downloads_dir;
if (base::PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_dir))
allowlist.push_back(downloads_dir);
}
// /run/imageloader is the root directory for all DLC packages. The "timeofday" package
// specifically contains assets required for one of ash's screen saver themes.
allowlist.push_back(
base::FilePath("/run/imageloader").Append(ash::kTimeOfDayDlcId));
return IsPathOnAllowlist(path, allowlist);
}
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_ANDROID)
// Returns true if access is allowed for |path|.
bool IsAccessAllowedAndroid(const base::FilePath& path) {
// Access to files in external storage is allowed.
base::FilePath external_storage_path;
base::PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE,
&external_storage_path);
if (external_storage_path.IsParent(path))
return true;
std::vector<base::FilePath> allowlist;
std::vector<base::FilePath> all_download_dirs =
base::android::GetAllPrivateDownloadsDirectories();
allowlist.insert(allowlist.end(), all_download_dirs.begin(),
all_download_dirs.end());
base::android::BuildInfo* build_info =
base::android::BuildInfo::GetInstance();
if (build_info->sdk_int() > base::android::SDK_VERSION_Q) {
std::vector<base::FilePath> all_external_download_volumes =
base::android::GetSecondaryStorageDownloadDirectories();
allowlist.insert(allowlist.end(), all_external_download_volumes.begin(),
all_external_download_volumes.end());
}
// allowlist of other allowed directories.
static const base::FilePath::CharType* const kLocalAccessAllowList[] = {
"/sdcard",
"/mnt/sdcard",
};
for (const auto* allowlisted_path : kLocalAccessAllowList)
allowlist.emplace_back(allowlisted_path);
return IsPathOnAllowlist(path, allowlist);
}
#endif // BUILDFLAG(IS_ANDROID)
bool IsAccessAllowedInternal(const base::FilePath& path,
const base::FilePath& profile_path) {
if (g_access_to_all_files_enabled)
return true;
#if BUILDFLAG(IS_CHROMEOS)
return IsAccessAllowedChromeOS(path, profile_path);
#elif BUILDFLAG(IS_ANDROID)
return IsAccessAllowedAndroid(path);
#else
return true;
#endif
}
} // namespace
// static
bool ChromeNetworkDelegate::IsAccessAllowed(
const base::FilePath& path,
const base::FilePath& profile_path) {
return IsAccessAllowedInternal(path, profile_path);
}
// static
bool ChromeNetworkDelegate::IsAccessAllowed(
const base::FilePath& path,
const base::FilePath& absolute_path,
const base::FilePath& profile_path) {
#if BUILDFLAG(IS_ANDROID)
// Android's allowlist relies on symbolic links (ex. /sdcard is allowed
// and commonly a symbolic link), thus do not check absolute paths.
return IsAccessAllowedInternal(path, profile_path);
#else
return (IsAccessAllowedInternal(path, profile_path) &&
IsAccessAllowedInternal(absolute_path, profile_path));
#endif
}
// static
void ChromeNetworkDelegate::EnableAccessToAllFilesForTesting(bool enabled) {
g_access_to_all_files_enabled = enabled;
}
|