mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Use high FD numbers in the forkserver to avoid collision with FDs mapped by the user
PiperOrigin-RevId: 242106285 Change-Id: I0f4bd130f8e66e6b47ad1d7311e0fff519aa9e90
This commit is contained in:
parent
6a65e63eae
commit
77ad64ac30
|
@ -57,6 +57,25 @@
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// "Moves" the old FD to the new FD number.
|
||||||
|
// The old FD will be closed, the new one is marked as CLOEXEC.
|
||||||
|
void MoveToFdNumber(int* old_fd, int new_fd) {
|
||||||
|
if (dup2(*old_fd, new_fd) == -1) {
|
||||||
|
SAPI_RAW_PLOG(FATAL, "Moving temporary to proper FD failed.");
|
||||||
|
}
|
||||||
|
close(*old_fd);
|
||||||
|
|
||||||
|
// Try to mark that FD as CLOEXEC.
|
||||||
|
int flags = fcntl(new_fd, F_GETFD);
|
||||||
|
if (flags == -1 || fcntl(new_fd, F_SETFD, flags | O_CLOEXEC) != 0) {
|
||||||
|
SAPI_RAW_PLOG(ERROR, "Marking FD as CLOEXEC failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
*old_fd = new_fd;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
pid_t ForkClient::SendRequest(const ForkRequest& request, int exec_fd,
|
pid_t ForkClient::SendRequest(const ForkRequest& request, int exec_fd,
|
||||||
|
@ -314,6 +333,10 @@ void ForkServer::LaunchChild(const ForkRequest& request, int execve_fd,
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t ForkServer::ServeRequest() const {
|
pid_t ForkServer::ServeRequest() const {
|
||||||
|
// Keep the low FD numbers clean so that client FD mappings don't interfer
|
||||||
|
// with us.
|
||||||
|
constexpr int kTargetExecFd = 1022;
|
||||||
|
|
||||||
ForkRequest fork_request;
|
ForkRequest fork_request;
|
||||||
if (!comms_->RecvProtoBuf(&fork_request)) {
|
if (!comms_->RecvProtoBuf(&fork_request)) {
|
||||||
if (comms_->IsTerminated()) {
|
if (comms_->IsTerminated()) {
|
||||||
|
@ -334,6 +357,9 @@ pid_t ForkServer::ServeRequest() const {
|
||||||
if (!comms_->RecvFD(&exec_fd)) {
|
if (!comms_->RecvFD(&exec_fd)) {
|
||||||
SAPI_RAW_LOG(FATAL, "Failed to receive Exec FD");
|
SAPI_RAW_LOG(FATAL, "Failed to receive Exec FD");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We're duping to a high number here to avoid colliding with the IPC FDs.
|
||||||
|
MoveToFdNumber(&exec_fd, kTargetExecFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the kernel notify us with SIGCHLD when the process terminates.
|
// Make the kernel notify us with SIGCHLD when the process terminates.
|
||||||
|
@ -381,12 +407,6 @@ pid_t ForkServer::ServeRequest() const {
|
||||||
if (sandboxee_pid == 0) {
|
if (sandboxee_pid == 0) {
|
||||||
LaunchChild(fork_request, exec_fd, comms_fd, uid, gid, user_ns_fd,
|
LaunchChild(fork_request, exec_fd, comms_fd, uid, gid, user_ns_fd,
|
||||||
fd_closer1.get());
|
fd_closer1.get());
|
||||||
|
|
||||||
// comms_fd has been remapped to 1023 (kSandbox2ClientCommsFD), so the
|
|
||||||
// original FD is not required anymore.
|
|
||||||
if (comms_fd != Comms::kSandbox2ClientCommsFD) {
|
|
||||||
close(comms_fd);
|
|
||||||
}
|
|
||||||
return sandboxee_pid;
|
return sandboxee_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,6 +503,7 @@ void ForkServer::SanitizeEnvironment(int client_fd) {
|
||||||
// Duplicate client's CommsFD onto fd=Comms::kSandbox2ClientCommsFD (1023).
|
// Duplicate client's CommsFD onto fd=Comms::kSandbox2ClientCommsFD (1023).
|
||||||
SAPI_RAW_CHECK(dup2(client_fd, Comms::kSandbox2ClientCommsFD) != -1,
|
SAPI_RAW_CHECK(dup2(client_fd, Comms::kSandbox2ClientCommsFD) != -1,
|
||||||
"while remapping client comms fd");
|
"while remapping client comms fd");
|
||||||
|
close(client_fd);
|
||||||
// Mark all file descriptors, except the standard ones (needed
|
// Mark all file descriptors, except the standard ones (needed
|
||||||
// for proper sandboxed process operations), as close-on-exec.
|
// for proper sandboxed process operations), as close-on-exec.
|
||||||
if (!sanitizer::SanitizeCurrentProcess(
|
if (!sanitizer::SanitizeCurrentProcess(
|
||||||
|
|
|
@ -87,8 +87,8 @@ static void StartGlobalForkServer() {
|
||||||
// Make sure the logs go stderr.
|
// Make sure the logs go stderr.
|
||||||
google::LogToStderr();
|
google::LogToStderr();
|
||||||
|
|
||||||
// Child.
|
// Close all non-essential FDs to keep newly opened FD numbers consistent.
|
||||||
close(sv[1]);
|
sandbox2::sanitizer::CloseAllFDsExcept({0, 1, 2, sv[0]});
|
||||||
|
|
||||||
// Make the process' name easily recognizable with ps/pstree.
|
// Make the process' name easily recognizable with ps/pstree.
|
||||||
if (prctl(PR_SET_NAME, "S2-FORK-SERV", 0, 0, 0) != 0) {
|
if (prctl(PR_SET_NAME, "S2-FORK-SERV", 0, 0, 0) != 0) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user