Skip to content

Commit

Permalink
[WIP] Use landlock
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Nov 21, 2024
1 parent fdca75c commit daa9de1
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ jobs:
mkdir wine_shims
rustc patches/bcryptprimitives.rs -Copt-level=3 -Clto=fat --out-dir wine_shims --target x86_64-pc-windows-gnu
echo "WINEPATH=$(pwd)/wine_shims" >> $GITHUB_ENV
wine echo || true # create ~/.wine to ensure wine works even when the build system is restricted using landlock
- name: Build
run: ./y.sh build --sysroot none
Expand Down
95 changes: 95 additions & 0 deletions build_system/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions build_system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ path = "main.rs"
unstable-features = [] # for rust-analyzer

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

[profile.dev]
debug = 1
75 changes: 75 additions & 0 deletions build_system/landlock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use std::env;
use std::path::Path;

use landlock::{
path_beneath_rules, Access, AccessFs, CompatLevel, Compatible, RulesetAttr, RulesetCreated,
RulesetCreatedAttr, ABI,
};

use crate::rustc_info::get_cargo_home;

/// Base landlock ruleset
///
/// This allows access to various essential system locations.
pub(super) fn base_ruleset() -> RulesetCreated {
let abi = ABI::V2;
let access_all = AccessFs::from_all(abi);
let access_read = AccessFs::from_read(abi);
landlock::Ruleset::default()
.set_compatibility(CompatLevel::SoftRequirement)
.handle_access(AccessFs::Refer)
.unwrap()
.set_compatibility(CompatLevel::BestEffort)
.handle_access(access_all)
.unwrap()
.create()
.unwrap()
.add_rules(path_beneath_rules(&["/"], access_read))
.unwrap()
.add_rules(path_beneath_rules(&["/tmp", "/dev/null"], access_all))
.unwrap()
}

pub(super) fn lock_fetch() {
let abi = ABI::V2;
let access_all = AccessFs::from_all(abi);
base_ruleset()
.add_rules(path_beneath_rules([env::current_dir().unwrap().join("download")], access_all))
.unwrap()
.restrict_self()
.unwrap();
}

pub(super) fn lock_build(cargo: &Path, frozen: bool) {
let abi = ABI::V2;
let access_all = AccessFs::from_all(abi);

let ruleset = base_ruleset()
.add_rules(path_beneath_rules(
&[env::current_dir().unwrap().join("build"), env::current_dir().unwrap().join("dist")],
access_all,
))
.unwrap()
.add_rules(path_beneath_rules(
&[
#[allow(deprecated)]
&std::env::home_dir().unwrap().join(".wine"),
Path::new("/run/user/"),
],
access_all,
))
.unwrap();

let ruleset = if frozen {
ruleset
} else {
ruleset
.add_rules(path_beneath_rules(
&[get_cargo_home(cargo).join("git"), get_cargo_home(cargo).join("registry")],
access_all,
))
.unwrap()
};

ruleset.restrict_self().unwrap();
}
17 changes: 15 additions & 2 deletions build_system/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ mod bench;
mod build_backend;
mod build_sysroot;
mod config;
#[cfg(target_os = "linux")]
mod landlock;
mod path;
mod prepare;
mod rustc_info;
Expand Down Expand Up @@ -130,15 +132,22 @@ fn main() {
out_dir = current_dir.join(out_dir);

if command == Command::Prepare {
prepare::prepare(&path::Dirs {
let dirs = path::Dirs {
source_dir: current_dir.clone(),
download_dir: download_dir
.map(|dir| current_dir.join(dir))
.unwrap_or_else(|| out_dir.join("download")),
build_dir: PathBuf::from("dummy_do_not_use"),
dist_dir: PathBuf::from("dummy_do_not_use"),
frozen,
});
};

std::fs::create_dir_all(&dirs.download_dir).unwrap();

#[cfg(target_os = "linux")]
landlock::lock_fetch();

prepare::prepare(&dirs);
process::exit(0);
}

Expand Down Expand Up @@ -186,6 +195,10 @@ fn main() {
};

std::fs::create_dir_all(&dirs.build_dir).unwrap();
std::fs::create_dir_all(&dirs.dist_dir).unwrap();

#[cfg(target_os = "linux")]
landlock::lock_build(&bootstrap_host_compiler.cargo, frozen);

{
// Make sure we always explicitly specify the target dir
Expand Down
19 changes: 19 additions & 0 deletions build_system/rustc_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ pub(crate) fn get_toolchain_name() -> String {
String::from_utf8(active_toolchain).unwrap().trim().split_once(' ').unwrap().0.to_owned()
}

#[cfg(target_os = "linux")]
pub(crate) fn get_cargo_home(cargo: &Path) -> PathBuf {
let cargo_home = Command::new(cargo)
.stderr(Stdio::inherit())
.args(&["-Zunstable-options", "config", "get", "--format=json-value", "home"])
.output()
.unwrap()
.stdout;
PathBuf::from(
String::from_utf8(cargo_home)
.unwrap()
.trim()
.strip_prefix('"')
.unwrap()
.strip_suffix('"')
.unwrap(),
)
}

pub(crate) fn get_cargo_path() -> PathBuf {
if let Ok(cargo) = std::env::var("CARGO") {
return PathBuf::from(cargo);
Expand Down

0 comments on commit daa9de1

Please sign in to comment.