// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/browser/network_sandbox.h" #include "base/dcheck_is_on.h" #include "base/files/file_util.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" #include "base/task/thread_pool.h" #include "base/trace_event/base_tracing.h" #include "build/build_config.h" #include "content/browser/network_sandbox_grant_result.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/network_service_util.h" #include "content/public/common/content_client.h" #include "sql/database.h" #if BUILDFLAG(IS_WIN) #include <windows.h> #include "base/win/security_util.h" #include "base/win/sid.h" #include "sandbox/policy/features.h" #endif // BUILDFLAG(IS_WIN) namespace content { namespace { // A filename that represents that the data contained within `data_directory` // has been migrated successfully and the data in `unsandboxed_data_path` is now // invalid. const base::FilePath::CharType kCheckpointFileName[] = …); // A platform specific set of parameters that is used when granting the sandbox // access to the network context data. struct SandboxParameters { … }; // Deletes the old data for a data file called `filename` from `old_path`. If // `file_path` refers to an SQL database then `is_sql` should be set to true, // and the journal file will also be deleted. // // Returns SandboxGrantResult::kSuccess if the all delete operations completed // successfully. Returns SandboxGrantResult::kFailedToDeleteData if a file could // not be deleted. SandboxGrantResult MaybeDeleteOldData( const base::FilePath& old_path, const std::optional<base::FilePath>& filename, bool is_sql) { … } // Copies data file called `filename` from `old_path` to `new_path` (which must // both be directories). If `file_path` refers to an SQL database then `is_sql` // should be set to true, and the journal file will also be migrated. // Destination files will be overwritten if they exist already. // // Returns SandboxGrantResult::kSuccess if the operation completed successfully. // Returns SandboxGrantResult::kFailedToCopyData if a file could not be copied. SandboxGrantResult MaybeCopyData(const base::FilePath& old_path, const base::FilePath& new_path, const std::optional<base::FilePath>& filename, bool is_sql) { … } // Deletes old data from `unsandboxed_data_path` if a migration operation has // been successful. SandboxGrantResult CleanUpOldData( network::mojom::NetworkContextParams* params) { … } // Grants the sandbox access to the specified `path`, which must be a directory // that exists. On Windows, the LPAC capability name should be supplied in the // `sandbox_params` to specify the name of the LPAC capability to be applied to // the path. On platforms which support directory transfer, the directory is // opened as a handle which is then sent to the NetworkService. // Returns true if the sandbox was successfully granted access to the path. bool MaybeGrantAccessToDataPath(const SandboxParameters& sandbox_params, network::TransferableDirectory* directory) { … } // See the description in the header file. // // This process has a few stages: // 1. Create and grant the sandbox access to the cache dir. // 2. If `data_directory` is not specified then the caller is using in-memory // storage and so there's nothing to do. END. // 3. If `unsandboxed_data_path` is not specified then the caller is not aware // of the sandbox or migration, and the steps terminate here with // `data_directory` used by the network context and END. // 4. If migration has already taken place, regardless of whether it's requested // this time, grant the sandbox access to the `data_directory` (since this needs // to be done every time), and terminate here with `data_directory` being used. // END. // 5. If migration is not requested, then terminate here with // `unsandboxed_data_path` being used. END. // 6. At this point, migration has been requested and hasn't already happened, // so begin a migration attempt. If any of these steps fail, then bail out, and // `unsandboxed_data_path` is used. // 7. Grant the sandbox access to the `data_directory` (this is done before // copying the files to use inherited ACLs when copying files on Windows). // 8. Copy all the data files one by one from the `unsandboxed_data_path` to the // `data_directory`. // 9. Once all the files have been copied, lay down the Checkpoint file in the // `data_directory`. // 10. Delete all the original files (if they exist) from // `unsandboxed_data_path`. SandboxGrantResult MaybeGrantSandboxAccessToNetworkContextData( const SandboxParameters& sandbox_params, network::mojom::NetworkContextParams* params) { … } } // namespace void GrantSandboxAccessOnThreadPool( network::mojom::NetworkContextParamsPtr params, base::OnceCallback<void(network::mojom::NetworkContextParamsPtr, SandboxGrantResult)> result_callback) { … } } // namespace content