mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-09 03:57:24 +00:00
The constants.json file is generated for compiling seccomp polices, but is only ever added to in newer versions of linux. Generating them in build.rs will cause the seccomp compiler to only understand constants and syscalls available on the build machine and fail if policy files try to allow syscalls not available. Putting the constants in version control will allow us to compile the policies regardless of how old the kernel headers on the build machine are. BUG=b:235858187 TEST=presubmit Change-Id: I1cfbb38f4687eb68b141f62c1c5fe6104b3f6456 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3988899 Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Auto-Submit: Dennis Kempin <denniskempin@google.com>
100 lines
3.8 KiB
Rust
100 lines
3.8 KiB
Rust
// Copyright 2022 The ChromiumOS Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
use std::env;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
|
|
fn rewrite_policies(seccomp_policy_path: &Path, rewrote_policy_folder: &Path) {
|
|
for entry in fs::read_dir(seccomp_policy_path).unwrap() {
|
|
let policy_file = entry.unwrap();
|
|
let policy_file_content = fs::read_to_string(policy_file.path()).unwrap();
|
|
let policy_file_content_rewrote =
|
|
policy_file_content.replace("/usr/share/policy/crosvm", ".");
|
|
fs::write(
|
|
rewrote_policy_folder.join(policy_file.file_name()),
|
|
policy_file_content_rewrote,
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
fn compile_policies(out_dir: &Path, rewrote_policy_folder: &Path, minijail_dir: &Path) {
|
|
let compiled_policy_folder = out_dir.join("policy_output");
|
|
fs::create_dir_all(&compiled_policy_folder).unwrap();
|
|
let mut include_all_bytes = String::from("std::collections::HashMap::from([\n");
|
|
for entry in fs::read_dir(&rewrote_policy_folder).unwrap() {
|
|
let policy_file = entry.unwrap();
|
|
if policy_file.path().extension().unwrap() == "policy" {
|
|
let output_file_path = compiled_policy_folder.join(
|
|
policy_file
|
|
.path()
|
|
.with_extension("bpf")
|
|
.file_name()
|
|
.unwrap(),
|
|
);
|
|
Command::new(minijail_dir.join("tools/compile_seccomp_policy.py"))
|
|
.arg("--arch-json")
|
|
.arg(rewrote_policy_folder.join("constants.json"))
|
|
.arg("--default-action")
|
|
.arg("trap")
|
|
.arg(policy_file.path())
|
|
.arg(&output_file_path)
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.expect("Compile bpf failed");
|
|
let s = format!(
|
|
r#"("{}", include_bytes!("{}").to_vec()),"#,
|
|
policy_file.path().file_stem().unwrap().to_str().unwrap(),
|
|
output_file_path.to_str().unwrap()
|
|
);
|
|
include_all_bytes += s.as_str();
|
|
}
|
|
}
|
|
include_all_bytes += "])";
|
|
fs::write(out_dir.join("bpf_includes.in"), include_all_bytes).unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
println!("cargo:rerun-if-changed=seccomp");
|
|
|
|
if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() != "unix" {
|
|
return;
|
|
}
|
|
|
|
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
let src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
|
let minijail_dir = if let Ok(minijail_dir_env) = env::var("MINIJAIL_DIR") {
|
|
PathBuf::from(minijail_dir_env)
|
|
} else {
|
|
src_dir.join("third_party/minijail")
|
|
};
|
|
|
|
// Disable embedding of seccomp policy files on ChromeOS builds.
|
|
println!("cargo:rerun-if-env-changed=CROSVM_BUILD_VARIANT");
|
|
if env::var("CROSVM_BUILD_VARIANT").unwrap_or_default() == "chromeos" {
|
|
fs::write(out_dir.join("bpf_includes.in"), "Default::default()").unwrap();
|
|
return;
|
|
}
|
|
|
|
// check policies exist for target architecuture
|
|
let seccomp_arch_name = match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
|
|
"armv7" => "arm".to_owned(),
|
|
x => x.to_owned(),
|
|
};
|
|
let seccomp_policy_path = src_dir.join("seccomp").join(&seccomp_arch_name);
|
|
assert!(
|
|
seccomp_policy_path.is_dir(),
|
|
"Seccomp policy dir doesn't exist"
|
|
);
|
|
|
|
let rewrote_policy_folder = out_dir.join("policy_input");
|
|
fs::create_dir_all(&rewrote_policy_folder).unwrap();
|
|
rewrite_policies(&seccomp_policy_path, &rewrote_policy_folder);
|
|
compile_policies(&out_dir, &rewrote_policy_folder, &minijail_dir);
|
|
}
|