From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 27 Mar 2024 10:47:48 +0100
Subject: refactor: expose file system access blocklist

This CL exposes the file system access blocklist publicly so that we can leverage
it in Electron and prevent drift from Chrome's blocklist. We should look for a way
to upstream this change to Chrome.

diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
index f56960eb24c9f30d87fe71d09a92a40b4ef35e8d..920e5824b899f02f7849a9fe5dd3c54be38e82a2 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -38,7 +38,6 @@
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
 #include "chrome/browser/ui/file_system_access_dialogs.h"
-#include "chrome/common/chrome_paths.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings.h"
@@ -222,118 +221,10 @@ bool MaybeIsLocalUNCPath(const base::FilePath& path) {
 }
 #endif
 
-// Sentinel used to indicate that no PathService key is specified for a path in
-// the struct below.
-constexpr const int kNoBasePathKey = -1;
-
-enum BlockType {
-  kBlockAllChildren,
-  kBlockNestedDirectories,
-  kDontBlockChildren
-};
-
-const struct {
-  // base::BasePathKey value (or one of the platform specific extensions to it)
-  // for a path that should be blocked. Specify kNoBasePathKey if |path| should
-  // be used instead.
-  int base_path_key;
-
-  // Explicit path to block instead of using |base_path_key|. Set to nullptr to
-  // use |base_path_key| on its own. If both |base_path_key| and |path| are set,
-  // |path| is treated relative to the path |base_path_key| resolves to.
-  const base::FilePath::CharType* path;
-
-  // If this is set to kDontBlockChildren, only the given path and its parents
-  // are blocked. If this is set to kBlockAllChildren, all children of the given
-  // path are blocked as well. Finally if this is set to kBlockNestedDirectories
-  // access is allowed to individual files in the directory, but nested
-  // directories are still blocked.
-  // The BlockType of the nearest ancestor of a path to check is what ultimately
-  // determines if a path is blocked or not. If a blocked path is a descendent
-  // of another blocked path, then it may override the child-blocking policy of
-  // its ancestor. For example, if /home blocks all children, but
-  // /home/downloads does not, then /home/downloads/file.ext will *not* be
-  // blocked.
-  BlockType type;
-} kBlockedPaths[] = {
-    // Don't allow users to share their entire home directory, entire desktop or
-    // entire documents folder, but do allow sharing anything inside those
-    // directories not otherwise blocked.
-    {base::DIR_HOME, nullptr, kDontBlockChildren},
-    {base::DIR_USER_DESKTOP, nullptr, kDontBlockChildren},
-    {chrome::DIR_USER_DOCUMENTS, nullptr, kDontBlockChildren},
-    // Similar restrictions for the downloads directory.
-    {chrome::DIR_DEFAULT_DOWNLOADS, nullptr, kDontBlockChildren},
-    {chrome::DIR_DEFAULT_DOWNLOADS_SAFE, nullptr, kDontBlockChildren},
-    // The Chrome installation itself should not be modified by the web.
-    {base::DIR_EXE, nullptr, kBlockAllChildren},
-    {base::DIR_MODULE, nullptr, kBlockAllChildren},
-    {base::DIR_ASSETS, nullptr, kBlockAllChildren},
-    // And neither should the configuration of at least the currently running
-    // Chrome instance (note that this does not take --user-data-dir command
-    // line overrides into account).
-    {chrome::DIR_USER_DATA, nullptr, kBlockAllChildren},
-    // ~/.ssh is pretty sensitive on all platforms, so block access to that.
-    {base::DIR_HOME, FILE_PATH_LITERAL(".ssh"), kBlockAllChildren},
-    // And limit access to ~/.gnupg as well.
-    {base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"), kBlockAllChildren},
-#if BUILDFLAG(IS_WIN)
-    // Some Windows specific directories to block, basically all apps, the
-    // operating system itself, as well as configuration data for apps.
-    {base::DIR_PROGRAM_FILES, nullptr, kBlockAllChildren},
-    {base::DIR_PROGRAM_FILESX86, nullptr, kBlockAllChildren},
-    {base::DIR_PROGRAM_FILES6432, nullptr, kBlockAllChildren},
-    {base::DIR_WINDOWS, nullptr, kBlockAllChildren},
-    {base::DIR_ROAMING_APP_DATA, nullptr, kBlockAllChildren},
-    {base::DIR_LOCAL_APP_DATA, nullptr, kBlockAllChildren},
-    {base::DIR_COMMON_APP_DATA, nullptr, kBlockAllChildren},
-    // Opening a file from an MTP device, such as a smartphone or a camera, is
-    // implemented by Windows as opening a file in the temporary internet files
-    // directory. To support that, allow opening files in that directory, but
-    // not whole directories.
-    {base::DIR_IE_INTERNET_CACHE, nullptr, kBlockNestedDirectories},
-#endif
-#if BUILDFLAG(IS_MAC)
-    // Similar Mac specific blocks.
-    {base::DIR_APP_DATA, nullptr, kBlockAllChildren},
-    {base::DIR_HOME, FILE_PATH_LITERAL("Library"), kBlockAllChildren},
-    // Allow access to other cloud files, such as Google Drive.
-    {base::DIR_HOME, FILE_PATH_LITERAL("Library/CloudStorage"),
-     kDontBlockChildren},
-    // Allow the site to interact with data from its corresponding natively
-    // installed (sandboxed) application. It would be nice to limit a site to
-    // access only _its_ corresponding natively installed application,
-    // but unfortunately there's no straightforward way to do that. See
-    // https://crbug.com/984641#c22.
-    {base::DIR_HOME, FILE_PATH_LITERAL("Library/Containers"),
-     kDontBlockChildren},
-    // Allow access to iCloud files...
-    {base::DIR_HOME, FILE_PATH_LITERAL("Library/Mobile Documents"),
-     kDontBlockChildren},
-    // ... which may also appear at this directory.
-    {base::DIR_HOME,
-     FILE_PATH_LITERAL("Library/Mobile Documents/com~apple~CloudDocs"),
-     kDontBlockChildren},
-#endif
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
-    // On Linux also block access to devices via /dev.
-    {kNoBasePathKey, FILE_PATH_LITERAL("/dev"), kBlockAllChildren},
-    // And security sensitive data in /proc and /sys.
-    {kNoBasePathKey, FILE_PATH_LITERAL("/proc"), kBlockAllChildren},
-    {kNoBasePathKey, FILE_PATH_LITERAL("/sys"), kBlockAllChildren},
-    // And system files in /boot and /etc.
-    {kNoBasePathKey, FILE_PATH_LITERAL("/boot"), kBlockAllChildren},
-    {kNoBasePathKey, FILE_PATH_LITERAL("/etc"), kBlockAllChildren},
-    // And block all of ~/.config, matching the similar restrictions on mac
-    // and windows.
-    {base::DIR_HOME, FILE_PATH_LITERAL(".config"), kBlockAllChildren},
-    // Block ~/.dbus as well, just in case, although there probably isn't much a
-    // website can do with access to that directory and its contents.
-    {base::DIR_HOME, FILE_PATH_LITERAL(".dbus"), kBlockAllChildren},
-#endif
-    // TODO(crbug.com/40095723): Refine this list, for example add
-    // XDG_CONFIG_HOME when it is not set ~/.config?
-};
+// This patch moves the deleted content from this file over to
+// chrome/browser/file_system_access/chrome_file_system_access_permission_context.h.
+// NOTE IF THERE IS A CONFLICT ABOVE, you will need to copy the changes in the
+// removed block over to chrome_file_system_access_permission_context.h.
 
 // Describes a rule for blocking a directory, which can be constructed
 // dynamically (based on state) or statically (from kBlockedPaths).
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
index dfbb68029c01d29616ae73e3d36fdcd24c64f39f..1865c7ae41c043e0a08dfd32e704919b016d5fbd 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
@@ -17,12 +17,13 @@
 #include "base/time/default_clock.h"
 #include "chrome/browser/file_system_access/file_system_access_features.h"
 #include "chrome/browser/file_system_access/file_system_access_permission_request_manager.h"
-#include "components/enterprise/buildflags/buildflags.h"
+#include "chrome/common/chrome_paths.h"
 #include "components/permissions/features.h"
 #include "components/permissions/object_permission_context_base.h"
 #include "content/public/browser/file_system_access_permission_context.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_manager.mojom-forward.h"
 
+
 #if !BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/permissions/one_time_permissions_tracker.h"
 #include "chrome/browser/permissions/one_time_permissions_tracker_observer.h"
@@ -30,7 +31,8 @@
 #include "chrome/browser/web_applications/web_app_install_manager_observer.h"
 #endif
 
-#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS)
+#if 0
+#include "components/enterprise/buildflags/buildflags.h"
 #include "chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h"
 #include "components/enterprise/common/files_scan_data.h"
 #endif
@@ -331,6 +333,119 @@ class ChromeFileSystemAccessPermissionContext
   // chrome://settings/content/filesystem UI.
   static constexpr char kPermissionPathKey[] = "path";
 
+  // Sentinel used to indicate that no PathService key is specified for a path in
+  // the struct below.
+  static constexpr int kNoBasePathKey = -1;
+
+  enum BlockType {
+    kBlockAllChildren,
+    kBlockNestedDirectories,
+    kDontBlockChildren
+  };
+
+  static constexpr struct {
+    // base::BasePathKey value (or one of the platform specific extensions to it)
+    // for a path that should be blocked. Specify kNoBasePathKey if |path| should
+    // be used instead.
+    int base_path_key;
+
+    // Explicit path to block instead of using |base_path_key|. Set to nullptr to
+    // use |base_path_key| on its own. If both |base_path_key| and |path| are set,
+    // |path| is treated relative to the path |base_path_key| resolves to.
+    const base::FilePath::CharType* path;
+
+    // If this is set to kDontBlockChildren, only the given path and its parents
+    // are blocked. If this is set to kBlockAllChildren, all children of the given
+    // path are blocked as well. Finally if this is set to kBlockNestedDirectories
+    // access is allowed to individual files in the directory, but nested
+    // directories are still blocked.
+    // The BlockType of the nearest ancestor of a path to check is what ultimately
+    // determines if a path is blocked or not. If a blocked path is a descendent
+    // of another blocked path, then it may override the child-blocking policy of
+    // its ancestor. For example, if /home blocks all children, but
+    // /home/downloads does not, then /home/downloads/file.ext will *not* be
+    // blocked.
+    BlockType type;
+  } kBlockedPaths[] = {
+      // Don't allow users to share their entire home directory, entire desktop or
+      // entire documents folder, but do allow sharing anything inside those
+      // directories not otherwise blocked.
+      {base::DIR_HOME, nullptr, kDontBlockChildren},
+      {base::DIR_USER_DESKTOP, nullptr, kDontBlockChildren},
+      {chrome::DIR_USER_DOCUMENTS, nullptr, kDontBlockChildren},
+      // Similar restrictions for the downloads directory.
+      {chrome::DIR_DEFAULT_DOWNLOADS, nullptr, kDontBlockChildren},
+      {chrome::DIR_DEFAULT_DOWNLOADS_SAFE, nullptr, kDontBlockChildren},
+      // The Chrome installation itself should not be modified by the web.
+      {base::DIR_EXE, nullptr, kBlockAllChildren},
+      {base::DIR_MODULE, nullptr, kBlockAllChildren},
+      {base::DIR_ASSETS, nullptr, kBlockAllChildren},
+      // And neither should the configuration of at least the currently running
+      // Chrome instance (note that this does not take --user-data-dir command
+      // line overrides into account).
+      {chrome::DIR_USER_DATA, nullptr, kBlockAllChildren},
+      // ~/.ssh is pretty sensitive on all platforms, so block access to that.
+      {base::DIR_HOME, FILE_PATH_LITERAL(".ssh"), kBlockAllChildren},
+      // And limit access to ~/.gnupg as well.
+      {base::DIR_HOME, FILE_PATH_LITERAL(".gnupg"), kBlockAllChildren},
+  #if BUILDFLAG(IS_WIN)
+      // Some Windows specific directories to block, basically all apps, the
+      // operating system itself, as well as configuration data for apps.
+      {base::DIR_PROGRAM_FILES, nullptr, kBlockAllChildren},
+      {base::DIR_PROGRAM_FILESX86, nullptr, kBlockAllChildren},
+      {base::DIR_PROGRAM_FILES6432, nullptr, kBlockAllChildren},
+      {base::DIR_WINDOWS, nullptr, kBlockAllChildren},
+      {base::DIR_ROAMING_APP_DATA, nullptr, kBlockAllChildren},
+      {base::DIR_LOCAL_APP_DATA, nullptr, kBlockAllChildren},
+      {base::DIR_COMMON_APP_DATA, nullptr, kBlockAllChildren},
+      // Opening a file from an MTP device, such as a smartphone or a camera, is
+      // implemented by Windows as opening a file in the temporary internet files
+      // directory. To support that, allow opening files in that directory, but
+      // not whole directories.
+      {base::DIR_IE_INTERNET_CACHE, nullptr, kBlockNestedDirectories},
+  #endif
+  #if BUILDFLAG(IS_MAC)
+      // Similar Mac specific blocks.
+      {base::DIR_APP_DATA, nullptr, kBlockAllChildren},
+      {base::DIR_HOME, FILE_PATH_LITERAL("Library"), kBlockAllChildren},
+      // Allow access to other cloud files, such as Google Drive.
+      {base::DIR_HOME, FILE_PATH_LITERAL("Library/CloudStorage"),
+      kDontBlockChildren},
+      // Allow the site to interact with data from its corresponding natively
+      // installed (sandboxed) application. It would be nice to limit a site to
+      // access only _its_ corresponding natively installed application,
+      // but unfortunately there's no straightforward way to do that. See
+      // https://crbug.com/984641#c22.
+      {base::DIR_HOME, FILE_PATH_LITERAL("Library/Containers"),
+      kDontBlockChildren},
+      // Allow access to iCloud files...
+      {base::DIR_HOME, FILE_PATH_LITERAL("Library/Mobile Documents"),
+      kDontBlockChildren},
+      // ... which may also appear at this directory.
+      {base::DIR_HOME,
+      FILE_PATH_LITERAL("Library/Mobile Documents/com~apple~CloudDocs"),
+      kDontBlockChildren},
+  #endif
+  #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+      // On Linux also block access to devices via /dev.
+      {kNoBasePathKey, FILE_PATH_LITERAL("/dev"), kBlockAllChildren},
+      // And security sensitive data in /proc and /sys.
+      {kNoBasePathKey, FILE_PATH_LITERAL("/proc"), kBlockAllChildren},
+      {kNoBasePathKey, FILE_PATH_LITERAL("/sys"), kBlockAllChildren},
+      // And system files in /boot and /etc.
+      {kNoBasePathKey, FILE_PATH_LITERAL("/boot"), kBlockAllChildren},
+      {kNoBasePathKey, FILE_PATH_LITERAL("/etc"), kBlockAllChildren},
+      // And block all of ~/.config, matching the similar restrictions on mac
+      // and windows.
+      {base::DIR_HOME, FILE_PATH_LITERAL(".config"), kBlockAllChildren},
+      // Block ~/.dbus as well, just in case, although there probably isn't much a
+      // website can do with access to that directory and its contents.
+      {base::DIR_HOME, FILE_PATH_LITERAL(".dbus"), kBlockAllChildren},
+  #endif
+      // TODO(crbug.com/40095723): Refine this list, for example add
+      // XDG_CONFIG_HOME when it is not set ~/.config?
+  };
+
  protected:
   SEQUENCE_CHECKER(sequence_checker_);
 
@@ -350,7 +465,7 @@ class ChromeFileSystemAccessPermissionContext
 
   void PermissionGrantDestroyed(PermissionGrantImpl* grant);
 
-#if BUILDFLAG(ENTERPRISE_CLOUD_CONTENT_ANALYSIS)
+#if 0
   void OnContentAnalysisComplete(
       std::vector<PathInfo> entries,
       EntriesAllowedByEnterprisePolicyCallback callback,
