Skip to content
This repository was archived by the owner on Mar 7, 2021. It is now read-only.

Commit 68ad09b

Browse files
committed
build.rs: Filter out known ABI-safe plugins (fixes #152)
1 parent 51688f9 commit 68ad09b

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

build.rs

+43-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::io::{BufRead, BufReader};
2-
use std::path::PathBuf;
2+
use std::path::{Path,PathBuf};
33
use std::{env, fs};
4+
use std::ffi::OsStr;
45

56
const INCLUDED_TYPES: &[&str] = &["file_system_type", "mode_t", "umode_t", "ctl_table"];
67
const INCLUDED_FUNCTIONS: &[&str] = &[
@@ -111,9 +112,22 @@ fn handle_kernel_symbols_cfg(symvers_path: &PathBuf) {
111112
}
112113
}
113114

115+
// Alist of plugin basename (without .so) to whether it leaves the ABI unchanged. See
116+
// https://github.com/fishinabarrel/linux-kernel-module-rust/issues/152#issuecomment-671219181
117+
const KNOWN_PLUGINS: &[(&str, bool)] = &[
118+
("cyc_complexity_plugin", true),
119+
("latent_entropy_plugin", true),
120+
("sancov_plugin", true),
121+
("structleak_plugin", true),
122+
("randomize_layout_plugin", false),
123+
("stackleak_plugin", true),
124+
("arm_ssp_per_task_plugin", true),
125+
];
126+
114127
// Takes the CFLAGS from the kernel Makefile and changes all the include paths to be absolute
115-
// instead of relative.
116-
fn prepare_cflags(cflags: &str, kernel_dir: &str) -> Vec<String> {
128+
// instead of relative. Also, filter out arguments to load or configure plugins and throw an error
129+
// if the requested plugin would change the ABI.
130+
fn prepare_cflags(cflags: &str, kernel_dir: &str) -> Option<Vec<String>> {
117131
let cflag_parts = shlex::split(&cflags).unwrap();
118132
let mut cflag_iter = cflag_parts.iter();
119133
let mut kernel_args = vec![];
@@ -128,11 +142,34 @@ fn prepare_cflags(cflags: &str, kernel_dir: &str) -> Vec<String> {
128142
} else {
129143
kernel_args.push(format!("{}/{}", kernel_dir, include_path));
130144
}
145+
} else if arg.starts_with("-fplugin=") {
146+
continue;
147+
let plugin_filename = arg.strip_prefix("-fplugin=").unwrap();
148+
let plugin_basename = Path::new(&plugin_filename).file_stem().unwrap();
149+
for (known_plugin, abi_safe) in KNOWN_PLUGINS {
150+
if plugin_basename == OsStr::new(known_plugin) {
151+
if !abi_safe {
152+
eprintln!("Your kernel uses the {:?} plugin, which changes the ABI in a way we can't handle :(", plugin_basename);
153+
return None;
154+
}
155+
if known_plugin == &"stackleak_plugin" {
156+
println!("cargo:warning=Rust code will not call stackleak, potentially weakining stackleak's protection.");
157+
}
158+
continue;
159+
}
160+
}
161+
eprintln!("Your kernel uses the {:?} plugin, which we don't know about.", plugin_basename);
162+
eprintln!("Edit linux-kernel-module-rust/build.rs if it doesn't change the ABI.");
163+
return None;
164+
} else if arg.starts_with("-fplugin-arg-") {
165+
continue;
131166
} else {
132167
kernel_args.push(arg.to_string());
133168
}
134169
}
135-
kernel_args
170+
kernel_args.push("-USTRUCTLEAK_PLUGIN".to_owned());
171+
kernel_args.push("-DMODULE".to_owned());
172+
Some(kernel_args)
136173
}
137174

138175
fn main() {
@@ -143,7 +180,8 @@ fn main() {
143180
let kernel_dir = env::var("abs_srctree").expect("Must be invoked from kernel makefile");
144181
let kernel_cflags = env::var("c_flags").expect("Add 'export c_flags' to Kbuild");
145182

146-
let kernel_args = prepare_cflags(&kernel_cflags, &kernel_dir);
183+
let kernel_args =
184+
prepare_cflags(&kernel_cflags, &kernel_dir).unwrap_or_else(|| std::process::exit(1));
147185

148186
let target = env::var("TARGET").unwrap();
149187

hello-world/Kbuild

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
obj-m := helloworld.o
22
helloworld-objs := hello_world.rust.o
33

4+
c_flags := $(filter-out -fplugin-%,${c_flags})
5+
46
CARGO ?= cargo
57

68
export c_flags

hello-world/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CC := ${CLANG}
66
endif
77

88
all:
9-
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=y
9+
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=y cmd_cc_o_c='$$(CC) $$(filter-out -D%_PLUGIN,$$(filter-out -fplugin%,$$(c_flags))) -c -o $$@ $$<'
1010

1111
clean:
1212
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) clean

0 commit comments

Comments
 (0)