Skip to content

Commit ecb10d2

Browse files
committed
[WIP] Use landlock
1 parent 6fbe4d9 commit ecb10d2

File tree

5 files changed

+193
-2
lines changed

5 files changed

+193
-2
lines changed

build_system/Cargo.lock

Lines changed: 95 additions & 0 deletions
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+
[dependencies]
15+
landlock = "0.4"
1416

1517
[profile.dev]
1618
debug = 1

build_system/landlock.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use std::env;
2+
use std::path::Path;
3+
4+
use landlock::{
5+
path_beneath_rules, Access, AccessFs, CompatLevel, Compatible, RulesetAttr, RulesetCreated,
6+
RulesetCreatedAttr, ABI,
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+
54+
let ruleset = if frozen {
55+
ruleset
56+
} else {
57+
ruleset
58+
.add_rules(path_beneath_rules(
59+
&[get_cargo_home(cargo).join("git"), get_cargo_home(cargo).join("registry")],
60+
access_all,
61+
))
62+
.unwrap()
63+
};
64+
65+
ruleset.restrict_self().unwrap();
66+
}

build_system/main.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod bench;
1212
mod build_backend;
1313
mod build_sysroot;
1414
mod config;
15+
mod landlock;
1516
mod path;
1617
mod prepare;
1718
mod rustc_info;
@@ -130,15 +131,21 @@ fn main() {
130131
out_dir = current_dir.join(out_dir);
131132

132133
if command == Command::Prepare {
133-
prepare::prepare(&path::Dirs {
134+
let dirs = path::Dirs {
134135
source_dir: current_dir.clone(),
135136
download_dir: download_dir
136137
.map(|dir| current_dir.join(dir))
137138
.unwrap_or_else(|| out_dir.join("download")),
138139
build_dir: PathBuf::from("dummy_do_not_use"),
139140
dist_dir: PathBuf::from("dummy_do_not_use"),
140141
frozen,
141-
});
142+
};
143+
144+
path::RelPath::DOWNLOAD.ensure_exists(&dirs);
145+
146+
landlock::lock_fetch();
147+
148+
prepare::prepare(&dirs);
142149
process::exit(0);
143150
}
144151

@@ -186,6 +193,9 @@ fn main() {
186193
};
187194

188195
path::RelPath::BUILD.ensure_exists(&dirs);
196+
path::RelPath::DIST.ensure_exists(&dirs);
197+
198+
landlock::lock_build(&bootstrap_host_compiler.cargo, frozen);
189199

190200
{
191201
// Make sure we always explicitly specify the target dir

build_system/rustc_info.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,24 @@ pub(crate) fn get_toolchain_name() -> String {
2727
String::from_utf8(active_toolchain).unwrap().trim().split_once(' ').unwrap().0.to_owned()
2828
}
2929

30+
pub(crate) fn get_cargo_home(cargo: &Path) -> PathBuf {
31+
let cargo_home = Command::new(cargo)
32+
.stderr(Stdio::inherit())
33+
.args(&["-Zunstable-options", "config", "get", "--format=json-value", "home"])
34+
.output()
35+
.unwrap()
36+
.stdout;
37+
PathBuf::from(
38+
String::from_utf8(cargo_home)
39+
.unwrap()
40+
.trim()
41+
.strip_prefix('"')
42+
.unwrap()
43+
.strip_suffix('"')
44+
.unwrap(),
45+
)
46+
}
47+
3048
pub(crate) fn get_cargo_path() -> PathBuf {
3149
if let Ok(cargo) = std::env::var("CARGO") {
3250
return PathBuf::from(cargo);

0 commit comments

Comments
 (0)