-
Notifications
You must be signed in to change notification settings - Fork 19
/
clone.rs
71 lines (56 loc) · 1.91 KB
/
clone.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
use aya_bpf::programs::ProbeContext;
use kunai_common::co_re::task_struct;
use super::*;
#[kprobe(name = "clone.enter.security_task_alloc")]
pub fn enter_wake_up_new_task(ctx: ProbeContext) -> u32 {
let rc = match unsafe { try_enter_wake_up_new_task(&ctx) } {
Ok(_) => error::BPF_PROG_SUCCESS,
Err(s) => {
log_err!(&ctx, s);
error::BPF_PROG_FAILURE
}
};
rc
}
unsafe fn try_enter_wake_up_new_task(ctx: &ProbeContext) -> ProbeResult<()> {
let new_task = task_struct::from_ptr(kprobe_arg!(ctx, 0)?);
let clone_flags = kprobe_arg!(&ctx, 1)?;
alloc::init()?;
let event = alloc::alloc_zero::<CloneEvent>()?;
// initializing task
event.init_from_task(Type::Clone, new_task)?;
// setting clone flags
event.data.flags = clone_flags;
let mm = core_read_kernel!(new_task, mm)?;
if mm.is_null() {
return Ok(());
}
let arg_start = core_read_kernel!(mm, arg_start)?;
let arg_len = core_read_kernel!(mm, arg_len)?;
// parsing executable
let exe_file = core_read_kernel!(mm, exe_file)?;
ignore_result!(inspect_err!(
event
.data
.executable
.core_resolve_file(&exe_file, MAX_PATH_DEPTH),
|e: &path::Error| warn!(ctx, "failed to resolve exe: {}", e.description())
));
// we check that arg_start is not a null pointer
if arg_start != 0 && arg_len != 0 {
ignore_result!(inspect_err!(
event
.data
.argv
.read_user_at(arg_start as *const u8, arg_len as u32),
|_| warn!(ctx, "failed to read argv")
));
}
// cgroup parsing
let cgroup = core_read_kernel!(new_task, sched_task_group, css, cgroup)?;
if let Err(e) = event.data.cgroup.resolve(cgroup) {
warn!(ctx, "failed to resolve cgroup: {}", e.description());
}
pipe_event(ctx, event);
Ok(())
}