mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 12:34:31 +00:00
a2ecd1eb50
We currently use cargo features to modify the build process, which makes them non-additive and prevents us from moving towards using --all-features in the future. To change build.rs behavior to integrate with downstream build systems (e.g. use pkg_config only on chromeos) we will use the newly added CROSVM_BUILD_VARIANT env variable. Currently only used by ChromeOS, but not limited to it. For now, CROSVM_BUILD_VARIANT=chromeos will prevent the embedding of seccomp policies. BUG=b:244618505 TEST=Test in combination with https://crrev.com/c/3923813 Change-Id: I2bfe999b5252740d57c73c4a85d73bd343c8259e Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3926325 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Dennis Kempin <denniskempin@google.com>
161 lines
5.6 KiB
Rust
161 lines
5.6 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 generate_preprocessed(minijail_dir: &Path, out_dir: &Path) {
|
|
let env_cc = cc::Build::new()
|
|
.get_compiler()
|
|
.path()
|
|
.as_os_str()
|
|
.to_owned();
|
|
|
|
Command::new(minijail_dir.join("gen_constants.sh"))
|
|
.env("CC", &env_cc)
|
|
.env("SRC", &minijail_dir)
|
|
.arg(out_dir.join("libconstants.gen.c"))
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.expect("Generate kernel constant table failed");
|
|
|
|
Command::new(minijail_dir.join("gen_syscalls.sh"))
|
|
.env("CC", &env_cc)
|
|
.env("SRC", &minijail_dir)
|
|
.arg(out_dir.join("libsyscalls.gen.c"))
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.expect("Generate syscall table failed");
|
|
}
|
|
|
|
fn generate_llvm_ir(minijail_dir: &Path, out_dir: &Path, target: &str) {
|
|
Command::new("clang")
|
|
.arg("-target")
|
|
.arg(target)
|
|
.arg("-S")
|
|
.arg("-emit-llvm")
|
|
.arg("-I")
|
|
.arg(minijail_dir)
|
|
.arg(out_dir.join("libconstants.gen.c"))
|
|
.arg(out_dir.join("libsyscalls.gen.c"))
|
|
.current_dir(&out_dir)
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.expect("Convert kernel constants and syscalls to llvm ir failed");
|
|
}
|
|
|
|
fn generate_constants_json(minijail_dir: &Path, out_dir: &Path) {
|
|
Command::new(minijail_dir.join("tools/generate_constants_json.py"))
|
|
.arg("--output")
|
|
.arg(out_dir.join("constants.json"))
|
|
.arg(out_dir.join("libconstants.gen.ll"))
|
|
.arg(out_dir.join("libsyscalls.gen.ll"))
|
|
.spawn()
|
|
.unwrap()
|
|
.wait()
|
|
.expect("Generate constants.json failed");
|
|
}
|
|
|
|
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(out_dir.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")
|
|
};
|
|
|
|
let target = env::var("TARGET").unwrap();
|
|
|
|
// 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(String::new()) == "chromeos" {
|
|
fs::write(out_dir.join("bpf_includes.in"), "Default::default()").unwrap();
|
|
return;
|
|
}
|
|
|
|
generate_preprocessed(&minijail_dir, &out_dir);
|
|
generate_llvm_ir(&minijail_dir, &out_dir, &target);
|
|
generate_constants_json(&minijail_dir, &out_dir);
|
|
|
|
// 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);
|
|
}
|