-
Notifications
You must be signed in to change notification settings - Fork 41
/
build.rs
148 lines (133 loc) · 4.26 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
fn main() {
// Check that a single TLS feature has been used
#[cfg(all(feature = "rustls-tls", feature = "native-tls"))]
compile_error!("You must select either the `rustls-tls` or the `native-tls` feature.");
#[cfg(not(any(feature = "rustls-tls", feature = "native-tls")))]
compile_error!("You must select either the `rustls-tls` or the `native-tls` feature.");
// generate the shell completions
shell_completions::generate();
// generate seccomp.bpf for the target architecture
seccomp::generate();
}
mod shell_completions {
#![allow(dead_code)] // Ignore unused warnings caused by including cli_args below.
extern crate structopt;
use structopt::clap::Shell;
include!("src/cli_args.rs");
pub fn generate() {
println!("cargo:rerun-if-env-changed=COMPLETIONS_DIR");
let directory = match std::env::var_os("COMPLETIONS_DIR") {
None => return,
Some(out_dir) => out_dir,
};
let mut app = CliArgs::clap();
app.gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, &directory);
app.gen_completions(env!("CARGO_PKG_NAME"), Shell::Fish, &directory);
app.gen_completions(env!("CARGO_PKG_NAME"), Shell::Zsh, &directory);
}
}
mod seccomp {
use libscmp::resolve_syscall_name;
use libscmp::Action;
use libscmp::Arch;
use libscmp::Filter;
use std::fs::File;
use std::os::unix::io::IntoRawFd;
use std::path::Path;
use std::str::FromStr;
pub fn generate() {
let mut ctx = Filter::new(Action::Allow).unwrap();
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");
// Get the target_arch configured in cargo to allow cross compiling
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").expect(
"Failed to compile seccomp filter, environment CARGO_CFG_TARGET_ARCH not found. This env is normally set by cargo.",
);
let target_arch = Arch::from_str(&target_arch)
.expect("Failed to compile seccomp filter, CARGO_CFG_TARGET_ARCH is not supported by crate libscmp.");
ctx.remove_arch(Arch::NATIVE).unwrap();
ctx.add_arch(target_arch).unwrap();
// Deny these syscalls
for syscall in &[
"_sysctl",
"acct",
"add_key",
"adjtimex",
"chroot",
"clock_adjtime",
"create_module",
"delete_module",
"fanotify_init",
"finit_module",
"get_kernel_syms",
"get_mempolicy",
"init_module",
"io_cancel",
"io_destroy",
"io_getevents",
"io_setup",
"io_submit",
"ioperm",
"iopl",
"ioprio_set",
"kcmp",
"kexec_file_load",
"kexec_load",
"keyctl",
"lookup_dcookie",
"mbind",
"migrate_pages",
"modify_ldt",
"mount",
"move_pages",
"name_to_handle_at",
"nfsservctl",
"open_by_handle_at",
"perf_event_open",
"pivot_root",
"process_vm_readv",
"process_vm_writev",
"ptrace",
"reboot",
"remap_file_pages",
"request_key",
"set_mempolicy",
"swapoff",
"swapon",
"sysfs",
"syslog",
"tuxcall",
"umount2",
"uselib",
"vmsplice",
] {
// Resolve the syscall number on the compiling host. (Not directly for the TARGET_ARCH, that mapping will be done automatically by libseccomp when the filter is exported.).
let syscall_num = resolve_syscall_name(syscall).unwrap_or_else(|| {
panic!(
"Failed to compile seccomp filter, syscall {} could not be resolved.",
syscall
)
});
// Add rule to filter. The syscall number will later be translated for all enabled architectures in the filter.
ctx.add_rule(Action::KillThread, syscall_num, &[])
.unwrap_or_else(|err| {
panic!(
"Failed to compile seccomp filter, failed to add rule for syscall {}({}). Error: {}",
syscall, syscall_num, err
);
});
}
println!("cargo:rerun-if-env-changed=OUT_DIR");
let out_dir = std::env::var("OUT_DIR")
.expect("Failed to save generated seccomp filter, no compile-time OUT_DIR defined.");
// Export the bpf file that will be "inlined" at RUA build time
let fd = File::create(Path::new(&out_dir).join("seccomp.bpf"))
.expect("Cannot create file seccomp.bpf in OUT_DIR.");
ctx.export_bpf(fd.into_raw_fd())
.expect("Failed to export seccomp.bpf.");
// Export the pfc file for debugging (not used for the actual build)
let fd = File::create(Path::new(&out_dir).join("seccomp.pfc"))
.expect("Cannot create file seccomp.pfc in OUT_DIR.");
ctx.export_pfc(fd.into_raw_fd())
.expect("Failed to export seccomp.pfc.");
}
}