Skip to content

Commit

Permalink
fix(process-monitor): make sure to extract absolute file paths on exec
Browse files Browse the repository at this point in the history
  • Loading branch information
MatteoNardi committed Mar 31, 2023
1 parent 5700f8d commit 95348e4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 21 deletions.
50 changes: 29 additions & 21 deletions crates/modules/process-monitor/probes.bpf.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
#include "buffer.bpf.h"
#include "common.bpf.h"
#include "get_path.bpf.h"
#include "output.bpf.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";
Expand Down Expand Up @@ -117,28 +118,23 @@ int BPF_PROG(sched_process_exec, struct task_struct *p, pid_t old_pid,
event->pid = tgid;
event->exec.argc = BPF_CORE_READ(bprm, argc);

// data_loc_filename is the offset from the beginning of the ctx structure
// of the executable filename
const char *filename = BPF_CORE_READ(bprm, filename);
buffer_index_init(&event->buffer, &event->exec.filename);
buffer_append_str(&event->buffer, &event->exec.filename, filename,
BUFFER_MAX);

struct task_struct *task = (struct task_struct *)bpf_get_current_task();
struct mm_struct *mm = BPF_CORE_READ(task, mm);
long start = BPF_CORE_READ(mm, arg_start);
long end = BPF_CORE_READ(mm, arg_end);
int len = end - start;
buffer_index_init(&event->buffer, &event->exec.argv);
buffer_append_user_memory(&event->buffer, &event->exec.argv, (void *)start,
len);

output_event(ctx, &events, event, sizeof(struct process_event),
event->buffer.len);
// We want to get the absolute path of the executable we're running.
// When executing a process with a relative path, bprm->filename won't be
// enough and we'll have to do a full path traversal. When starts with /
// though, we can just copy it, as an optimization.
const char *bprm_filename = BPF_CORE_READ(bprm, filename);
char first_character = 0;
bpf_core_read(&first_character, 1, bprm_filename);
if (first_character == '/') {
buffer_index_init(&event->buffer, &event->exec.filename);
buffer_append_str(&event->buffer, &event->exec.filename, bprm_filename,
BUFFER_MAX);
} else {
struct path path = BPF_CORE_READ(bprm, file, f_path);
get_path_str(path.dentry, &path, &event->buffer, &event->exec.filename);
}

char image[MAX_IMAGE_LEN];
__builtin_memset(&image, 0, sizeof(image));
bpf_core_read_str(&image, MAX_IMAGE_LEN, filename);
char *image = (char *)&event->buffer.buffer;

// Check whitelist
char *res = bpf_map_lookup_elem(&whitelist, image);
Expand All @@ -154,6 +150,18 @@ int BPF_PROG(sched_process_exec, struct task_struct *p, pid_t old_pid,
update_interest(tgid, true, res);
}

struct task_struct *task = (struct task_struct *)bpf_get_current_task();
struct mm_struct *mm = BPF_CORE_READ(task, mm);
long start = BPF_CORE_READ(mm, arg_start);
long end = BPF_CORE_READ(mm, arg_end);
int len = end - start;
buffer_index_init(&event->buffer, &event->exec.argv);
buffer_append_user_memory(&event->buffer, &event->exec.argv, (void *)start,
len);

output_event(ctx, &events, event, sizeof(struct process_event),
event->buffer.len);

return 0;
}

Expand Down
25 changes: 25 additions & 0 deletions crates/modules/process-monitor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ pub mod test_suite {
tests: vec![
fork_event(),
exec_event(),
relative_exec_event(),
exit_event(),
exit_event_no_thread(),
inherit_policy(),
Expand Down Expand Up @@ -269,6 +270,30 @@ pub mod test_suite {
})
}

fn relative_exec_event() -> TestCase {
TestCase::new("relative_exec_event", async {
let mut child_pid = Pid::from_raw(0);
let echo_buff = which("echo").unwrap();
let echo_path = echo_buff.as_path().to_str().unwrap().to_string();
test_runner()
.run(|| {
let mut child = std::process::Command::new("./echo")
.current_dir(echo_buff.as_path().parent().unwrap())
.arg("-n")
.spawn()
.unwrap();
child_pid = Pid::from_raw(child.id() as i32);
child.wait().unwrap();
})
.await
.expect_event_from_pid(
child_pid,
event_check!(ProcessEvent::Exec, (filename, echo_path, "exec filename")),
)
.report()
})
}

fn exit_event() -> TestCase {
TestCase::new("exit_event", async {
let mut child_pid = Pid::from_raw(0);
Expand Down

0 comments on commit 95348e4

Please sign in to comment.