Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/jail/build.rs
5392 views
1
// Copyright 2022 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::env;
6
use std::ffi::OsStr;
7
use std::fs;
8
use std::path::Path;
9
use std::path::PathBuf;
10
use std::process::Command;
11
12
use rayon::prelude::*;
13
14
fn rewrite_policies(seccomp_policy_path: &Path, rewrote_policy_folder: &Path) {
15
for entry in fs::read_dir(seccomp_policy_path).unwrap() {
16
let policy_file = entry.unwrap();
17
let policy_file_content = fs::read_to_string(policy_file.path()).unwrap();
18
let policy_file_content_rewrote =
19
policy_file_content.replace("/usr/share/policy/crosvm", ".");
20
fs::write(
21
rewrote_policy_folder.join(policy_file.file_name()),
22
policy_file_content_rewrote,
23
)
24
.unwrap();
25
}
26
}
27
28
fn compile_policy(
29
compile_script: &Path,
30
out_dir: &Path,
31
compile_policy_folder_relative: &Path,
32
output_folder: &Path,
33
policy_file: &fs::DirEntry,
34
) -> String {
35
let output_file_path_relative = compile_policy_folder_relative.join(
36
policy_file
37
.path()
38
.with_extension("bpf")
39
.file_name()
40
.unwrap(),
41
);
42
let status = Command::new(compile_script)
43
.arg("--arch-json")
44
.arg(output_folder.join("constants.json"))
45
.arg("--default-action")
46
.arg("trap")
47
.arg(policy_file.path())
48
.arg(out_dir.join(&output_file_path_relative))
49
.spawn()
50
.unwrap()
51
.wait()
52
.expect("Spawning the bpf compiler failed");
53
if !status.success() {
54
panic!("Compile bpf failed");
55
}
56
format!(
57
r#"("{}", include_bytes!("{}").to_vec()),"#,
58
policy_file.path().file_stem().unwrap().to_str().unwrap(),
59
output_file_path_relative.to_str().unwrap()
60
)
61
}
62
63
fn compile_policies(out_dir: &Path, rewrote_policy_folder: &Path, compile_seccomp_policy: &Path) {
64
let compiled_policy_folder_relative = Path::new("policy_output");
65
fs::create_dir_all(out_dir.join(compiled_policy_folder_relative)).unwrap();
66
let mut include_all_bytes = String::from("std::collections::HashMap::from([\n");
67
68
let entries = fs::read_dir(rewrote_policy_folder)
69
.unwrap()
70
.map(|ent| ent.unwrap())
71
.collect::<Vec<_>>();
72
73
let s = entries
74
.par_iter()
75
.filter(|ent| ent.path().extension() == Some(OsStr::new("policy")))
76
.map(|policy_file| {
77
compile_policy(
78
compile_seccomp_policy,
79
out_dir,
80
compiled_policy_folder_relative,
81
rewrote_policy_folder,
82
policy_file,
83
)
84
})
85
.collect::<Vec<_>>()
86
.join("");
87
include_all_bytes += &s;
88
89
include_all_bytes += "])";
90
fs::write(out_dir.join("bpf_includes.in"), include_all_bytes).unwrap();
91
}
92
93
fn main() {
94
println!("cargo:rerun-if-changed=build.rs");
95
println!("cargo:rerun-if-changed=seccomp");
96
97
if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() != "unix" {
98
return;
99
}
100
101
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
102
let src_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
103
104
let compile_seccomp_policy = if let Ok(path) = which::which("compile_seccomp_policy") {
105
// If `compile_seccomp_policy` exists in the path (e.g. ChromeOS builds), use it.
106
path
107
// Otherwise, use compile_seccomp_policy.py from the minijail submodule.
108
} else if let Ok(minijail_dir_env) = env::var("MINIJAIL_DIR") {
109
PathBuf::from(minijail_dir_env).join("tools/compile_seccomp_policy.py")
110
} else if let Ok(compile_seccomp_policy_env) = env::var("COMPILE_SECCOMP_POLICY") {
111
PathBuf::from(compile_seccomp_policy_env)
112
} else {
113
src_dir.join("../third_party/minijail/tools/compile_seccomp_policy.py")
114
};
115
116
// check policies exist for target architecture
117
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
118
let seccomp_policy_path = src_dir.join("seccomp").join(target_arch);
119
assert!(
120
seccomp_policy_path.is_dir(),
121
"Seccomp policy dir doesn't exist"
122
);
123
124
let rewrote_policy_folder = out_dir.join("policy_input");
125
fs::create_dir_all(&rewrote_policy_folder).unwrap();
126
rewrite_policies(&seccomp_policy_path, &rewrote_policy_folder);
127
compile_policies(&out_dir, &rewrote_policy_folder, &compile_seccomp_policy);
128
}
129
130