Skip to content

Commit e629048

Browse files
committed
use checks.c for hook check
1 parent 5924b96 commit e629048

3 files changed

Lines changed: 40 additions & 19 deletions

File tree

fact-ebpf/src/bpf/checks.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ int BPF_PROG(check_path_unlink_supports_bpf_d_path, struct path* dir, struct den
1313
bpf_printk("dir: %s", p->path);
1414
return 0;
1515
}
16+
17+
SEC("lsm/inode_set_acl")
18+
int BPF_PROG(check_inode_set_acl, struct mnt_idmap* idmap, struct dentry* dentry, const char* acl_name,
19+
struct posix_acl* kacl) {
20+
return 0;
21+
}

fact/src/bpf/checks.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use log::debug;
44

55
pub(super) struct Checks {
66
pub(super) path_hooks_support_bpf_d_path: bool,
7+
pub(super) supports_inode_set_acl: bool,
78
}
89

910
impl Checks {
@@ -12,15 +13,31 @@ impl Checks {
1213
.load(fact_ebpf::CHECKS_OBJ)
1314
.context("Failed to load checks.o")?;
1415

15-
let prog = obj
16-
.program_mut("check_path_unlink_supports_bpf_d_path")
17-
.context("Failed to find 'check_path_unlink_supports_bpf_d_path' program")?;
18-
let prog: &mut Lsm = prog.try_into()?;
19-
let path_hooks_support_bpf_d_path = prog.load("path_unlink", btf).is_ok();
20-
debug!("path_unlink_supports_bpf_d_path: {path_hooks_support_bpf_d_path}");
16+
let path_hooks_support_bpf_d_path = Self::probe_hook(
17+
&mut obj,
18+
"check_path_unlink_supports_bpf_d_path",
19+
"path_unlink",
20+
btf,
21+
);
22+
debug!("path_hooks_support_bpf_d_path: {path_hooks_support_bpf_d_path}");
23+
24+
let supports_inode_set_acl =
25+
Self::probe_hook(&mut obj, "check_inode_set_acl", "inode_set_acl", btf);
26+
debug!("supports_inode_set_acl: {supports_inode_set_acl}");
2127

2228
Ok(Checks {
2329
path_hooks_support_bpf_d_path,
30+
supports_inode_set_acl,
2431
})
2532
}
33+
34+
fn probe_hook(obj: &mut aya::Ebpf, prog_name: &str, hook: &str, btf: &Btf) -> bool {
35+
let Some(prog) = obj.program_mut(prog_name) else {
36+
return false;
37+
};
38+
let Ok(prog): Result<&mut Lsm, _> = prog.try_into() else {
39+
return false;
40+
};
41+
prog.load(hook, btf).is_ok()
42+
}
2643
}

fact/src/bpf/mod.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@ mod checks;
2424

2525
const RINGBUFFER_NAME: &str = "rb";
2626

27-
/// Hooks that may not be available on all supported kernels. If these
28-
/// fail to load, FACT will log a warning and continue without them.
29-
const OPTIONAL_HOOKS: &[&str] = &["inode_set_acl"];
30-
3127
pub struct Bpf {
3228
obj: Ebpf,
29+
checks: Checks,
3330

3431
tx: mpsc::Sender<Event>,
3532

@@ -68,6 +65,7 @@ impl Bpf {
6865
let paths = Vec::new();
6966
let mut bpf = Bpf {
7067
obj,
68+
checks,
7169
tx,
7270
paths,
7371
paths_config,
@@ -182,17 +180,17 @@ impl Bpf {
182180
let Some(hook) = name.strip_prefix("trace_") else {
183181
bail!("Invalid hook name: {name}");
184182
};
185-
let result = match prog {
186-
Program::Lsm(prog) => prog.load(hook, btf),
183+
184+
// Skip hooks that the kernel doesn't support
185+
if hook == "inode_set_acl" && !self.checks.supports_inode_set_acl {
186+
info!("Skipping {hook}: not supported on this kernel");
187+
continue;
188+
}
189+
190+
match prog {
191+
Program::Lsm(prog) => prog.load(hook, btf)?,
187192
u => unimplemented!("{u:?}"),
188193
};
189-
if let Err(e) = result {
190-
if OPTIONAL_HOOKS.contains(&hook) {
191-
warn!("Optional hook {hook} not available on this kernel, skipping: {e}");
192-
continue;
193-
}
194-
return Err(e.into());
195-
}
196194
}
197195
Ok(())
198196
}

0 commit comments

Comments
 (0)