blob: 0e6225c3ca5872c9d5551f1f6d1aaa7a52a6eaec [file]
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/launch_native_messaging_host_process.h"
#include <unistd.h>
#include <string_view>
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/process/launch.h"
namespace remoting {
ProcessLaunchResult LaunchNativeMessagingHostProcess(
const base::FilePath& binary_path,
intptr_t /* unused_parent_window_handle */,
bool elevate_process,
base::File& read_handle,
base::File& write_handle) {
base::ScopedFD parent_read_fd, child_stdout_fd;
if (!base::CreatePipe(&parent_read_fd, &child_stdout_fd)) {
PLOG(ERROR) << "Failed to create the read pipe.";
return PROCESS_LAUNCH_RESULT_FAILED;
}
base::ScopedFD child_stdin_fd, parent_write_fd;
if (!base::CreatePipe(&child_stdin_fd, &parent_write_fd)) {
PLOG(ERROR) << "Failed to create the write pipe.";
return PROCESS_LAUNCH_RESULT_FAILED;
}
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
base::LaunchOptions options;
if (elevate_process) {
// `pkexec <binary_path>`
command_line.SetProgram(base::FilePath("pkexec"));
command_line.AppendArg(binary_path.value());
// pkexec is a setuid binary, so we must allow new privileges.
options.allow_new_privs = true;
} else {
command_line.SetProgram(binary_path);
}
options.fds_to_remap.emplace_back(child_stdin_fd.get(), STDIN_FILENO);
options.fds_to_remap.emplace_back(child_stdout_fd.get(), STDOUT_FILENO);
base::Process process = base::LaunchProcess(command_line, options);
if (!process.IsValid()) {
LOG(ERROR) << "Failed to launch " << (elevate_process ? "elevated " : "")
<< "native messaging host.";
return PROCESS_LAUNCH_RESULT_FAILED;
}
read_handle = base::File(parent_read_fd.release());
write_handle = base::File(parent_write_fd.release());
// Child FDs in the parent process will be automatically released.
return PROCESS_LAUNCH_RESULT_SUCCESS;
}
} // namespace remoting