first commit

This commit is contained in:
guochao
2023-11-01 16:17:51 +08:00
commit 1a5d0ebbb7
15 changed files with 1779 additions and 0 deletions

View File

@ -0,0 +1,63 @@
use std::{collections::HashSet, str::FromStr};
use proc_macro::*;
use quote::{quote, format_ident, TokenStreamExt};
#[proc_macro]
pub fn generate(input: TokenStream) -> TokenStream {
let wd = std::path::PathBuf::from_str(&std::env::var("CARGO_MANIFEST_DIR").unwrap()).unwrap();
let syscall_filepath =
wd.join(std::env::var("X2T_SYSCALLS_FILE").unwrap_or("x2t-syscalls.txt".to_string()));
if let Some(syscalls) = option_env!("X2T_SYSCALLS") {
generate_from(input.clone(), syscalls.to_lowercase(), ":").into()
} else if let Ok(syscalls) = std::fs::read_to_string(&syscall_filepath) {
generate_from(input.clone(), syscalls, "\n").into()
} else {
panic!("either specify a X2T_SYSCALLS environment variable with values seperated by colon or write the allowed syscalls line by line into {}", syscall_filepath.to_string_lossy());
}
}
fn generate_from(input: proc_macro::TokenStream, buf: String, sep: &str) -> proc_macro2::TokenStream {
// TODO: improve generate rules to restrict arguments
let mut tokens = Vec::new();
let mut syscalls = HashSet::new();
let raw_syscall_pattern = regex::Regex::new("^\\s*([a-z_][a-z0-9_]*)").unwrap();
let strace_pattern = regex::Regex::new("^\\d+ ([a-z_][a-z0-9_]*)").unwrap();
for s in buf.split(sep) {
// s can be a
// - a name matched by [[:space:]]*(?P<syscall>[a-z_][a-z0-9_]*)
// - strace line matched by [[:digit:]] (?P<syscall>[a-z_][a-z0-9_]*)
for pattern in [&raw_syscall_pattern, &strace_pattern] {
if let Some(capture) = pattern.captures(s) {
let (_, [syscall_name]) = capture.extract();
syscalls.insert(syscall_name.to_string());
break;
}
}
}
let mut syscalls: Vec<String> = syscalls.iter().map(|s| s.to_owned()).collect();
syscalls.sort();
let hook: proc_macro2::TokenStream = input.into();
for syscall_name in syscalls {
let libc_name = format_ident!("SYS_{}", syscall_name);
tokens.push(
quote! {
{
let syscall_nr = nix::libc::#libc_name;
let syscall_name = #syscall_name;
filter.add_rule_conditional(ScmpAction::Allow, syscall_nr as i32, &[])?;
#hook
}
}
);
}
quote! {
#(#tokens);*
}
}