Refactor Forkserver::LaunchChild

PiperOrigin-RevId: 561331391
Change-Id: Ia96187ac1aff25a729c92dfc937f48cc0ae64342
This commit is contained in:
Wiktor Garbacz 2023-08-30 07:11:49 -07:00 committed by Copybara-Service
parent 09a48bac06
commit 5802d5b681

View File

@ -281,16 +281,7 @@ void ForkServer::LaunchChild(const ForkRequest& request, int execve_fd,
"Forkserver mode is unspecified"); "Forkserver mode is unspecified");
const bool will_execve = execve_fd != -1; const bool will_execve = execve_fd != -1;
const bool should_sandbox = request.mode() == FORKSERVER_FORK_EXECVE_SANDBOX;
// Prepare the arguments before sandboxing (if needed), as doing it after
// sandoxing can cause syscall violations (e.g. related to memory management).
std::vector<std::string> args;
std::vector<std::string> envs;
if (will_execve) {
PrepareExecveArgs(request, &args, &envs);
}
SanitizeEnvironment();
absl::StatusOr<absl::flat_hash_set<int>> open_fds = sanitizer::GetListOfFDs(); absl::StatusOr<absl::flat_hash_set<int>> open_fds = sanitizer::GetListOfFDs();
if (!open_fds.ok()) { if (!open_fds.ok()) {
@ -298,6 +289,7 @@ void ForkServer::LaunchChild(const ForkRequest& request, int execve_fd,
std::string(open_fds.status().message()).c_str()); std::string(open_fds.status().message()).c_str());
open_fds = absl::flat_hash_set<int>(); open_fds = absl::flat_hash_set<int>();
} }
SanitizeEnvironment();
InitializeNamespaces(request, uid, gid, avoid_pivot_root); InitializeNamespaces(request, uid, gid, avoid_pivot_root);
@ -331,40 +323,44 @@ void ForkServer::LaunchChild(const ForkRequest& request, int execve_fd,
signaling_fd.Close(); signaling_fd.Close();
status_fd.Close(); status_fd.Close();
if (request.mode() == FORKSERVER_FORK_EXECVE_SANDBOX) { Client c(comms_);
// Prepare the arguments before sandboxing (if needed), as doing it after
// sandoxing can cause syscall violations (e.g. related to memory management).
std::vector<std::string> args;
std::vector<std::string> envs;
if (will_execve) {
PrepareExecveArgs(request, &args, &envs);
}
// Sandboxing can be enabled either here - just before execve, or somewhere // Sandboxing can be enabled either here - just before execve, or somewhere
// inside the executed binary (e.g. after basic structures have been // inside the executed binary (e.g. after basic structures have been
// initialized, and resources acquired). In the latter case, it's up to the // initialized, and resources acquired). In the latter case, it's up to the
// sandboxed binary to establish proper Comms channel (using // sandboxed binary to establish proper Comms channel (using
// Comms::kSandbox2ClientCommsFD) and call sandbox2::Client::SandboxMeHere() // Comms::kSandbox2ClientCommsFD) and call sandbox2::Client::SandboxMeHere()
if (should_sandbox) {
// Create a Comms object here and not above, as we know we will execve and
// therefore not call the Comms destructor, which would otherwise close the
// comms file descriptor, which we do not want for the general case.
Client c(comms_);
// The following client calls are basically SandboxMeHere. We split it so // The following client calls are basically SandboxMeHere. We split it so
// that we can set up the envp after we received the file descriptors but // that we can set up the envp after we received the file descriptors but
// before we enable the syscall filter. // before we enable the syscall filter.
c.PrepareEnvironment(&execve_fd); c.PrepareEnvironment(&execve_fd);
if (comms_->GetConnectionFD() != Comms::kSandbox2ClientCommsFD) { if (comms_->GetConnectionFD() != Comms::kSandbox2ClientCommsFD) {
envs.push_back(absl::StrCat(Comms::kSandbox2CommsFDEnvVar, "=", envs.push_back(absl::StrCat(Comms::kSandbox2CommsFDEnvVar, "=",
comms_->GetConnectionFD())); comms_->GetConnectionFD()));
} }
envs.push_back(c.GetFdMapEnvVar()); envs.push_back(c.GetFdMapEnvVar());
}
// Convert args and envs before enabling sandbox (it'll allocate which might // Convert args and envs before enabling sandbox (it'll allocate which might
// be blocked). // be blocked).
util::CharPtrArray argv = util::CharPtrArray::FromStringVector(args); util::CharPtrArray argv = util::CharPtrArray::FromStringVector(args);
util::CharPtrArray envp = util::CharPtrArray::FromStringVector(envs); util::CharPtrArray envp = util::CharPtrArray::FromStringVector(envs);
if (should_sandbox) {
c.EnableSandbox(); c.EnableSandbox();
ExecuteProcess(execve_fd, argv.data(), envp.data());
} }
if (will_execve) { if (will_execve) {
ExecuteProcess(execve_fd, util::CharPtrArray::FromStringVector(args).data(), ExecuteProcess(execve_fd, argv.data(), envp.data());
util::CharPtrArray::FromStringVector(envs).data());
} }
} }