blob: e1be1a3e2b753d68a686814e2bef050de430c6f1 [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "debugd/src/scheduler_configuration_tool.h"
#include "debugd/src/error_utils.h"
#include "debugd/src/process_with_output.h"
#include "debugd/src/sandboxed_process.h"
#include <string>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/stringprintf.h>
#include <brillo/errors/error_codes.h>
#include <build/build_config.h>
#include <build/buildflag.h>
#include <chromeos/dbus/service_constants.h>
namespace debugd {
namespace {
constexpr char kErrorPath[] =
"org.chromium.debugd.SchedulerConfigurationPolicyError";
constexpr bool IsX86_64() {
#if defined(__x86_64__)
return true;
#else
return false;
#endif
}
// Executes a helper process with the expectation that any message printed to
// stderr indicates a failure that should be passed back over D-Bus.
// Returns false if any errors launching the process occur. Returns true
// otherwise, and sets |exit_status| if it isn't null.
bool RunHelper(const std::string& command,
const ProcessWithOutput::ArgList& arguments,
int* exit_status,
brillo::ErrorPtr* error) {
std::string helper_path;
if (!SandboxedProcess::GetHelperPath(command, &helper_path)) {
DEBUGD_ADD_ERROR(error, kErrorPath, "Path too long");
return false;
}
// Note: This runs the helper as root and without a sandbox only because the
// helper immediately drops privileges and enforces its own sandbox. debugd
// should not be used to launch unsandboxed executables.
std::string stderr;
int result = ProcessWithOutput::RunProcess(
helper_path, arguments, true /*requires_root*/,
true /* disable_sandbox */, nullptr, nullptr, &stderr, error);
if (!stderr.empty()) {
DEBUGD_ADD_ERROR(error, kErrorPath, stderr.c_str());
return false;
}
if (exit_status)
*exit_status = result;
return true;
}
} // namespace
bool SchedulerConfigurationTool::SetPolicy(const std::string& policy,
brillo::ErrorPtr* error) {
if (!IsX86_64()) {
DEBUGD_ADD_ERROR(error, kErrorPath, "Invalid architecture");
return false;
}
int exit_status;
bool result = RunHelper("scheduler_configuration_helper",
ProcessWithOutput::ArgList{"--policy=" + policy},
&exit_status, error);
bool status = result && (exit_status == 0);
if (!status) {
DEBUGD_ADD_ERROR(error, kErrorPath,
"scheduler_configuration_helper failed");
}
return status;
}
} // namespace debugd