Skip to content

Commit c537dcb

Browse files
committed
[WIP] Use landlock
1 parent ed6fbc2 commit c537dcb

File tree

5 files changed

+207
-3
lines changed

5 files changed

+207
-3
lines changed

build_system/Cargo.lock

Lines changed: 96 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_system/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ path = "main.rs"
1111
unstable-features = [] # for rust-analyzer
1212

1313
# Do not add any dependencies
14+
[target.'cfg(target_os = "linux")'.dependencies]
15+
landlock = "0.4"
1416

1517
[profile.dev]
1618
debug = 1

build_system/landlock.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::env;
2+
use std::path::Path;
3+
4+
use landlock::{
5+
ABI, Access, AccessFs, CompatLevel, Compatible, RulesetAttr, RulesetCreated,
6+
RulesetCreatedAttr, path_beneath_rules,
7+
};
8+
9+
use crate::rustc_info::get_cargo_home;
10+
11+
/// Base landlock ruleset
12+
///
13+
/// This allows access to various essential system locations.
14+
pub(super) fn base_ruleset() -> RulesetCreated {
15+
let abi = ABI::V2;
16+
let access_all = AccessFs::from_all(abi);
17+
let access_read = AccessFs::from_read(abi);
18+
landlock::Ruleset::default()
19+
.set_compatibility(CompatLevel::SoftRequirement)
20+
.handle_access(AccessFs::Refer)
21+
.unwrap()
22+
.set_compatibility(CompatLevel::BestEffort)
23+
.handle_access(access_all)
24+
.unwrap()
25+
.create()
26+
.unwrap()
27+
.add_rules(path_beneath_rules(&["/"], access_read))
28+
.unwrap()
29+
.add_rules(path_beneath_rules(&["/tmp", "/dev/null"], access_all))
30+
.unwrap()
31+
}
32+
33+
pub(super) fn lock_fetch() {
34+
let abi = ABI::V2;
35+
let access_all = AccessFs::from_all(abi);
36+
base_ruleset()
37+
.add_rules(path_beneath_rules([env::current_dir().unwrap().join("download")], access_all))
38+
.unwrap()
39+
.restrict_self()
40+
.unwrap();
41+
}
42+
43+
pub(super) fn lock_build(cargo: &Path, frozen: bool) {
44+
let abi = ABI::V2;
45+
let access_all = AccessFs::from_all(abi);
46+
47+
let ruleset = base_ruleset()
48+
.add_rules(path_beneath_rules(
49+
&[env::current_dir().unwrap().join("build"), env::current_dir().unwrap().join("dist")],
50+
access_all,
51+
))
52+
.unwrap()
53+
.add_rules(path_beneath_rules(
54+
&[
55+
#[allow(deprecated)]
56+
&std::env::home_dir().unwrap().join(".wine"),
57+
Path::new("/run/user/"),
58+
],
59+
access_all,
60+
))
61+
.unwrap();
62+
63+
let ruleset = if frozen {
64+
ruleset
65+
} else {
66+
ruleset
67+
.add_rules(path_beneath_rules(
68+
&[get_cargo_home(cargo).join("git"), get_cargo_home(cargo).join("registry")],
69+
access_all,
70+
))
71+
.unwrap()
72+
};
73+
74+
ruleset.restrict_self().unwrap();
75+
}

build_system/main.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ mod bench;
1212
mod build_backend;
1313
mod build_sysroot;
1414
mod config;
15+
#[cfg(target_os = "linux")]
16+
mod landlock;
1517
mod path;
1618
mod prepare;
1719
mod rustc_info;
@@ -132,15 +134,22 @@ fn main() {
132134
out_dir = current_dir.join(out_dir);
133135

134136
if command == Command::Prepare {
135-
prepare::prepare(&path::Dirs {
137+
let dirs = path::Dirs {
136138
source_dir: current_dir.clone(),
137139
download_dir: download_dir
138140
.map(|dir| current_dir.join(dir))
139141
.unwrap_or_else(|| out_dir.join("download")),
140142
build_dir: PathBuf::from("dummy_do_not_use"),
141143
dist_dir: PathBuf::from("dummy_do_not_use"),
142144
frozen,
143-
});
145+
};
146+
147+
std::fs::create_dir_all(&dirs.download_dir).unwrap();
148+
149+
#[cfg(target_os = "linux")]
150+
landlock::lock_fetch();
151+
152+
prepare::prepare(&dirs);
144153
process::exit(0);
145154
}
146155

@@ -184,6 +193,10 @@ fn main() {
184193
};
185194

186195
std::fs::create_dir_all(&dirs.build_dir).unwrap();
196+
std::fs::create_dir_all(&dirs.dist_dir).unwrap();
197+
198+
#[cfg(target_os = "linux")]
199+
landlock::lock_build(&bootstrap_host_compiler.cargo, frozen);
187200

188201
{
189202
// Make sure we always explicitly specify the target dir

build_system/rustc_info.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ pub(crate) fn get_toolchain_name() -> String {
2121
String::from_utf8(active_toolchain).unwrap().trim().split_once(' ').unwrap().0.to_owned()
2222
}
2323

24+
#[cfg(target_os = "linux")]
25+
pub(crate) fn get_cargo_home(cargo: &Path) -> PathBuf {
26+
let cargo_home = Command::new(cargo)
27+
.stderr(Stdio::inherit())
28+
.args(&["-Zunstable-options", "config", "get", "--format=json-value", "home"])
29+
.output()
30+
.unwrap()
31+
.stdout;
32+
PathBuf::from(
33+
String::from_utf8(cargo_home)
34+
.unwrap()
35+
.trim()
36+
.strip_prefix('"')
37+
.unwrap()
38+
.strip_suffix('"')
39+
.unwrap(),
40+
)
41+
}
42+
2443
pub(crate) fn get_cargo_path() -> PathBuf {
2544
if let Ok(cargo) = std::env::var("CARGO") {
2645
return PathBuf::from(cargo);

0 commit comments

Comments
 (0)