Skip to content

Commit

Permalink
[Resource file sharing]: Pass BrowserInitParams to Utility process as…
Browse files Browse the repository at this point in the history
… File Descriptor

This CL passes BrowserInitParams to Utility process as Memory FD.
FD map is contained in BrowserChildProcessHost::DataToPassAsFD with
files_to_preload.

This CL also changes files_to_preload field to limit only on posix
platforms.
Note that files_to_preload value was only used from posix even without
this CL, so it won't affect the behavior.

This change aims to let utility process be able to obtain ash dir from BrowserInitParams. This feature will be implemented in the later CL.
This is a part of resource file sharing work and doesn't affect the
behavior for now.

Bug: 1253280
Change-Id: Ibd92217974e2e763c58ab71af85ee50a13d2c03e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3599393
Reviewed-by: Bo Liu <boliu@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Avi Drissman <avi@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Commit-Queue: Eriko Kurimoto <elkurin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1001877}
  • Loading branch information
elkurin authored and Chromium LUCI CQ committed May 11, 2022
1 parent 1b94009 commit 9c83b40
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 52 deletions.
4 changes: 2 additions & 2 deletions chrome/app/chrome_main_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1041,8 +1041,8 @@ void ChromeMainDelegate::PreSandboxStartup() {
InitializeUserDataDir(base::CommandLine::ForCurrentProcess());

#if BUILDFLAG(IS_CHROMEOS_LACROS)
// Initialize BrowserInitParams only for browser process and zygote process.
if (process_type.empty() || process_type == switches::kZygoteProcess) {
if (process_type.empty() || process_type == switches::kZygoteProcess ||
process_type == switches::kUtilityProcess) {
// TODO(elkurin): Add comments here when resource loading using ash
// resources is implemented.
const crosapi::mojom::BrowserInitParams* init_params =
Expand Down
2 changes: 2 additions & 0 deletions content/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2613,6 +2613,8 @@ source_set("browser") {
deps += [
"//chromeos/crosapi/mojom",
"//chromeos/lacros",
"//chromeos/startup",
"//chromeos/startup:constants",
]
}

Expand Down
32 changes: 17 additions & 15 deletions content/browser/browser_child_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -217,19 +217,9 @@ void BrowserChildProcessHostImpl::Launch(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
bool terminate_on_shutdown) {
LaunchWithPreloadedFiles(std::move(delegate), std::move(cmd_line),
/*files_to_preload=*/{}, terminate_on_shutdown);
}

void BrowserChildProcessHostImpl::LaunchWithPreloadedFiles(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::map<std::string, base::FilePath> files_to_preload,
bool terminate_on_shutdown) {
GetContentClient()->browser()->AppendExtraCommandLineSwitches(cmd_line.get(),
data_.id);
LaunchWithoutExtraCommandLineSwitches(
std::move(delegate), std::move(cmd_line), std::move(files_to_preload),
LaunchWithFileData(
std::move(delegate), std::move(cmd_line),
/*file_data=*/std::make_unique<ChildProcessLauncherFileData>(),
terminate_on_shutdown);
}

Expand Down Expand Up @@ -279,10 +269,22 @@ void BrowserChildProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
child_process_host_->AddFilter(filter->GetFilter());
}

void BrowserChildProcessHostImpl::LaunchWithFileData(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown) {
GetContentClient()->browser()->AppendExtraCommandLineSwitches(cmd_line.get(),
data_.id);
LaunchWithoutExtraCommandLineSwitches(
std::move(delegate), std::move(cmd_line), std::move(file_data),
terminate_on_shutdown);
}

void BrowserChildProcessHostImpl::LaunchWithoutExtraCommandLineSwitches(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::map<std::string, base::FilePath> files_to_preload,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const base::CommandLine& browser_command_line =
Expand Down Expand Up @@ -331,7 +333,7 @@ void BrowserChildProcessHostImpl::LaunchWithoutExtraCommandLineSwitches(
base::BindRepeating(&BrowserChildProcessHostImpl::OnMojoError,
weak_factory_.GetWeakPtr(),
base::ThreadTaskRunnerHandle::Get()),
std::move(files_to_preload), terminate_on_shutdown);
std::move(file_data), terminate_on_shutdown);
ShareMetricsAllocatorToProcess();

if (!has_legacy_ipc_channel_)
Expand Down
15 changes: 9 additions & 6 deletions content/browser/browser_child_process_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ class BrowserChildProcessHostImpl
void Launch(std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
bool terminate_on_shutdown) override;
void LaunchWithPreloadedFiles(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::map<std::string, base::FilePath> files_to_preload,
bool terminate_on_shutdown) override;
const ChildProcessData& GetData() override;
ChildProcessHost* GetHost() override;
ChildProcessTerminationInfo GetTerminationInfo(bool known_dead) override;
Expand Down Expand Up @@ -113,14 +108,22 @@ class BrowserChildProcessHostImpl
// Adds an IPC message filter.
void AddFilter(BrowserMessageFilter* filter);

// Same as Launch(), but the process is launched with preloaded files and file
// descriptors containing in `file_data`.
void LaunchWithFileData(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown);

// Unlike Launch(), AppendExtraCommandLineSwitches will not be called
// in this function. If AppendExtraCommandLineSwitches has been called before
// reaching launch, call this function instead so the command line switches
// won't be appended twice
void LaunchWithoutExtraCommandLineSwitches(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
std::map<std::string, base::FilePath> files_to_preload,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown);

static void HistogramBadMessageTerminated(ProcessType process_type);
Expand Down
9 changes: 6 additions & 3 deletions content/browser/child_process_launcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ void ChildProcessLauncherPriority::WriteIntoTrace(
#endif
}

ChildProcessLauncherFileData::ChildProcessLauncherFileData() = default;

ChildProcessLauncherFileData::~ChildProcessLauncherFileData() = default;

#if BUILDFLAG(IS_ANDROID)
bool ChildProcessLauncher::Client::CanUseWarmUpConnection() {
return true;
Expand All @@ -65,7 +69,7 @@ ChildProcessLauncher::ChildProcessLauncher(
Client* client,
mojo::OutgoingInvitation mojo_invitation,
const mojo::ProcessErrorCallback& process_error_callback,
std::map<std::string, base::FilePath> files_to_preload,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown)
: client_(client),
starting_(true),
Expand All @@ -85,8 +89,7 @@ ChildProcessLauncher::ChildProcessLauncher(
#if BUILDFLAG(IS_ANDROID)
client_->CanUseWarmUpConnection(),
#endif
std::move(mojo_invitation), process_error_callback,
std::move(files_to_preload));
std::move(mojo_invitation), process_error_callback, std::move(file_data));
helper_->StartLaunchOnClientThread();
}

Expand Down
40 changes: 36 additions & 4 deletions content/browser/child_process_launcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "build/build_config.h"
#include "content/browser/child_process_launcher_helper.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/result_codes.h"
Expand All @@ -33,6 +34,10 @@
#include "base/win/windows_types.h"
#endif

#if BUILDFLAG(IS_POSIX)
#include "base/files/scoped_file.h"
#endif

namespace base {
class CommandLine;
}
Expand Down Expand Up @@ -145,6 +150,29 @@ struct ChildProcessLauncherPriority {
#endif
};

// Data to pass as file descriptors.
struct ChildProcessLauncherFileData {
ChildProcessLauncherFileData();
ChildProcessLauncherFileData(const ChildProcessLauncherFileData& others) =
delete;
ChildProcessLauncherFileData& operator=(const ChildProcessLauncherFileData&) =
delete;
~ChildProcessLauncherFileData();

#if BUILDFLAG(IS_POSIX)
// Files opened by the browser and passed as corresponding file descriptors
// in the child process.
// Currently only supported on Linux, ChromeOS and Android platforms.
std::map<std::string, base::FilePath> files_to_preload;

// Map of file descriptors to pass. This is used instead of
// `files_to_preload` when the data is already contained as a file
// descriptor.
// Currently only supported on POSIX platforms.
std::map<int, base::ScopedFD> additional_remapped_fds;
#endif
};

// Launches a process asynchronously and notifies the client of the process
// handle when it's available. It's used to avoid blocking the calling thread
// on the OS since often it can take > 100 ms to create the process.
Expand Down Expand Up @@ -172,23 +200,27 @@ class CONTENT_EXPORT ChildProcessLauncher {
// this object destructs, it will be terminated.
// Takes ownership of cmd_line.
//
// If |process_error_callback| is provided, it will be called if a Mojo error
// If `process_error_callback` is provided, it will be called if a Mojo error
// is encountered when processing messages from the child process. This
// callback must be safe to call from any thread.
//
// |files_to_preload| is a map of key names to file paths. These files will be
// `file_data` consists of 2 members:
// files_to_preload: a map of key names to file paths. These files will be
// opened by the browser process and corresponding file descriptors inherited
// by the new child process, accessible using the corresponding key via some
// platform-specific mechanism (such as base::FileDescriptorStore on POSIX).
// Currently only supported on POSIX platforms.
// Currently only supported on Linux, ChromeOS and Android platforms.
// additional_remapped_fds: is a map of file descriptors to pass. This is
// used instead of files_to_preload when the data is already contained as a
// file descriptor. Currently only supported on POSIX platforms.
ChildProcessLauncher(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
std::unique_ptr<base::CommandLine> cmd_line,
int child_process_id,
Client* client,
mojo::OutgoingInvitation mojo_invitation,
const mojo::ProcessErrorCallback& process_error_callback,
std::map<std::string, base::FilePath> files_to_preload,
std::unique_ptr<ChildProcessLauncherFileData> file_data,
bool terminate_on_shutdown = true);

ChildProcessLauncher(const ChildProcessLauncher&) = delete;
Expand Down
4 changes: 2 additions & 2 deletions content/browser/child_process_launcher_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ ChildProcessLauncherHelper::ChildProcessLauncherHelper(
#endif
mojo::OutgoingInvitation mojo_invitation,
const mojo::ProcessErrorCallback& process_error_callback,
std::map<std::string, base::FilePath> files_to_preload)
std::unique_ptr<ChildProcessLauncherFileData> file_data)
: child_process_id_(child_process_id),
client_task_runner_(base::SequencedTaskRunnerHandle::Get()),
command_line_(std::move(command_line)),
Expand All @@ -87,7 +87,7 @@ ChildProcessLauncherHelper::ChildProcessLauncherHelper(
terminate_on_shutdown_(terminate_on_shutdown),
mojo_invitation_(std::move(mojo_invitation)),
process_error_callback_(process_error_callback),
files_to_preload_(std::move(files_to_preload))
file_data_(std::move(file_data))
#if BUILDFLAG(IS_ANDROID)
,
can_use_warm_up_connection_(can_use_warm_up_connection)
Expand Down
6 changes: 4 additions & 2 deletions content/browser/child_process_launcher_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/zygote/zygote_buildflags.h"
#include "mojo/public/cpp/platform/platform_channel.h"
Expand Down Expand Up @@ -56,6 +57,7 @@ namespace content {

class ChildProcessLauncher;
class SandboxedProcessLauncherDelegate;
struct ChildProcessLauncherFileData;
struct ChildProcessLauncherPriority;
struct ChildProcessTerminationInfo;

Expand Down Expand Up @@ -104,7 +106,7 @@ class ChildProcessLauncherHelper :
#endif
mojo::OutgoingInvitation mojo_invitation,
const mojo::ProcessErrorCallback& process_error_callback,
std::map<std::string, base::FilePath> files_to_preload);
std::unique_ptr<ChildProcessLauncherFileData> file_data);

// The methods below are defined in the order they are called.

Expand Down Expand Up @@ -240,7 +242,7 @@ class ChildProcessLauncherHelper :
bool terminate_on_shutdown_;
mojo::OutgoingInvitation mojo_invitation_;
const mojo::ProcessErrorCallback process_error_callback_;
const std::map<std::string, base::FilePath> files_to_preload_;
std::unique_ptr<ChildProcessLauncherFileData> file_data_;

#if BUILDFLAG(IS_MAC)
std::unique_ptr<sandbox::SeatbeltExecClient> seatbelt_exec_client_;
Expand Down
7 changes: 6 additions & 1 deletion content/browser/child_process_launcher_helper_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ ChildProcessLauncherHelper::GetFilesToMap() {
std::unique_ptr<PosixFileDescriptorInfo> files_to_register =
CreateDefaultPosixFilesToMap(
child_process_id(), mojo_channel_->remote_endpoint(),
files_to_preload_, GetProcessType(), command_line());
file_data_->files_to_preload, GetProcessType(), command_line());

#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
base::MemoryMappedFile::Region icu_region;
Expand All @@ -92,6 +92,11 @@ ChildProcessLauncherHelper::GetFilesToMap() {
bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
PosixFileDescriptorInfo& files_to_register,
base::LaunchOptions* options) {
for (const auto& remapped_fd : file_data_->additional_remapped_fds) {
options->fds_to_remap.emplace_back(remapped_fd.second.get(),
remapped_fd.first);
}

return true;
}

Expand Down
9 changes: 7 additions & 2 deletions content/browser/child_process_launcher_helper_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ std::unique_ptr<FileMappedForLaunch>
ChildProcessLauncherHelper::GetFilesToMap() {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
return CreateDefaultPosixFilesToMap(
child_process_id(), mojo_channel_->remote_endpoint(), files_to_preload_,
GetProcessType(), command_line());
child_process_id(), mojo_channel_->remote_endpoint(),
file_data_->files_to_preload, GetProcessType(), command_line());
}

bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
Expand All @@ -56,6 +56,11 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->fds_to_remap.push_back(std::make_pair(sandbox_fd, GetSandboxFD()));
}

for (const auto& remapped_fd : file_data_->additional_remapped_fds) {
options->fds_to_remap.emplace_back(remapped_fd.second.get(),
remapped_fd.first);
}

options->environment = delegate_->GetEnvironment();

return true;
Expand Down
5 changes: 5 additions & 0 deletions content/browser/child_process_launcher_helper_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
base::StringPrintf("%s%d", sandbox::switches::kSeatbeltClient, pipe));
}

for (const auto& remapped_fd : file_data_->additional_remapped_fds) {
options->fds_to_remap.emplace_back(remapped_fd.second.get(),
remapped_fd.first);
}

return true;
}

Expand Down
6 changes: 5 additions & 1 deletion content/browser/gpu/gpu_process_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "components/viz/common/features.h"
#include "components/viz/common/switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
Expand All @@ -44,6 +45,7 @@
#include "content/common/child_process.mojom.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
Expand Down Expand Up @@ -1232,7 +1234,9 @@ bool GpuProcessHost::LaunchGpuProcess() {
// Call LaunchWithoutExtraCommandLineSwitches() so the command line switches
// will not be appended twice.
process_->LaunchWithoutExtraCommandLineSwitches(
std::move(delegate), std::move(cmd_line), /*files_to_preload=*/{}, true);
std::move(delegate), std::move(cmd_line),
/*file_data=*/
std::make_unique<ChildProcessLauncherFileData>(), true);
process_launched_ = true;

if (kind_ == GPU_PROCESS_KIND_SANDBOXED) {
Expand Down
9 changes: 8 additions & 1 deletion content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
#include "content/common/content_switches_internal.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/pseudonymization_salt.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_or_resource_context.h"
#include "content/public/browser/browser_thread.h"
Expand Down Expand Up @@ -1753,14 +1754,20 @@ bool RenderProcessHostImpl::Init() {
std::unique_ptr<SandboxedProcessLauncherDelegate> sandbox_delegate =
std::make_unique<RendererSandboxedProcessLauncherDelegate>();
#endif

auto file_data = std::make_unique<ChildProcessLauncherFileData>();
#if BUILDFLAG(IS_POSIX)
file_data->files_to_preload = GetV8SnapshotFilesToPreload();
#endif

// Spawn the child process asynchronously to avoid blocking the UI thread.
// As long as there's no renderer prefix, we can use the zygote process
// at this stage.
child_process_launcher_ = std::make_unique<ChildProcessLauncher>(
std::move(sandbox_delegate), std::move(cmd_line), GetID(), this,
std::move(mojo_invitation_),
base::BindRepeating(&RenderProcessHostImpl::OnMojoError, id_),
GetV8SnapshotFilesToPreload());
std::move(file_data));
channel_->Pause();

// In single process mode, browser-side tracing and memory will cover the
Expand Down

0 comments on commit 9c83b40

Please sign in to comment.