Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process execute failed #4233

Merged
merged 2 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 50 additions & 50 deletions api/v1beta1/event.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/v1beta1/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ enum EventId {
module_load = 1082;
module_free = 1083;
execute_finished = 1084;
security_bprm_creds_for_exec = 1085;
process_execute_failed_internal = 1085;

// Events originated from user-space
net_packet_ipv4 = 2000;
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/events/builtin/extra/process_execute_failed.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Relevant from kernel version 5.8 onwards, matching the `security_bprm_creds_for_
## Example Use Case

```console
./tracee -e process_execution_failed
./tracee -e process_execute_failed
```

## Issues
Expand Down
3 changes: 1 addition & 2 deletions pkg/ebpf/c/maps.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ enum tail_call_id_e
TAIL_SCHED_PROCESS_EXEC_EVENT_SUBMIT,
TAIL_VFS_READ,
TAIL_VFS_READV,
TAIL_PROCESS_EXECUTE_FAILED1,
TAIL_PROCESS_EXECUTE_FAILED2,
TAIL_PROCESS_EXECUTE_FAILED,
TAIL_HIDDEN_KERNEL_MODULE_PROC,
TAIL_HIDDEN_KERNEL_MODULE_KSET,
TAIL_HIDDEN_KERNEL_MODULE_MOD_TREE,
Expand Down
116 changes: 46 additions & 70 deletions pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ int syscall__accept4(void *ctx)

struct socket *old_sock = (struct socket *) saved_args.args[0];
struct socket *new_sock = (struct socket *) saved_args.args[1];
u32 sockfd = (u32) saved_args.args[2];
u64 sockfd = (u32) saved_args.args[2];
geyslan marked this conversation as resolved.
Show resolved Hide resolved

if (new_sock == NULL) {
return -1;
Expand Down Expand Up @@ -4940,31 +4940,32 @@ statfunc int submit_process_execute_failed(struct pt_regs *ctx, program_data_t *
struct file *file = get_file_ptr_from_bprm(bprm);

const char *path = get_binprm_filename(bprm);
save_str_to_buf(&p->event->args_buf, (void *) path, 0);
save_str_to_buf(&p->event->args_buf, (void *) path, 2);

void *binary_path = get_path_str(__builtin_preserve_access_index(&file->f_path));
save_str_to_buf(&p->event->args_buf, binary_path, 1);
save_str_to_buf(&p->event->args_buf, binary_path, 3);

dev_t binary_device_id = get_dev_from_file(file);
save_to_submit_buf(&p->event->args_buf, &binary_device_id, sizeof(dev_t), 2);
save_to_submit_buf(&p->event->args_buf, &binary_device_id, sizeof(dev_t), 4);

unsigned long binary_inode_number = get_inode_nr_from_file(file);
save_to_submit_buf(&p->event->args_buf, &binary_inode_number, sizeof(unsigned long), 3);
save_to_submit_buf(&p->event->args_buf, &binary_inode_number, sizeof(unsigned long), 5);

u64 binary_ctime = get_ctime_nanosec_from_file(file);
save_to_submit_buf(&p->event->args_buf, &binary_ctime, sizeof(u64), 4);
save_to_submit_buf(&p->event->args_buf, &binary_ctime, sizeof(u64), 6);

umode_t binary_inode_mode = get_inode_mode_from_file(file);
save_to_submit_buf(&p->event->args_buf, &binary_inode_mode, sizeof(umode_t), 5);
save_to_submit_buf(&p->event->args_buf, &binary_inode_mode, sizeof(umode_t), 7);

const char *interpreter_path = get_binprm_interp(bprm);
save_str_to_buf(&p->event->args_buf, (void *) interpreter_path, 6);
save_str_to_buf(&p->event->args_buf, (void *) interpreter_path, 8);

bpf_tail_call(ctx, &prog_array, TAIL_PROCESS_EXECUTE_FAILED1);
bpf_tail_call(ctx, &prog_array, TAIL_PROCESS_EXECUTE_FAILED);
return -1;
}

statfunc int execute_failed_tail1(struct pt_regs *ctx, u32 tail_call_id)
SEC("kprobe/process_execute_failed_tail")
int process_execute_failed_tail(struct pt_regs *ctx)
{
program_data_t p = {};
if (!init_tailcall_program_data(&p, ctx))
Expand All @@ -4974,91 +4975,38 @@ statfunc int execute_failed_tail1(struct pt_regs *ctx, u32 tail_call_id)
struct file *stdin_file = get_struct_file_from_fd(0);

unsigned short stdin_type = get_inode_mode_from_file(stdin_file) & S_IFMT;
save_to_submit_buf(&p.event->args_buf, &stdin_type, sizeof(unsigned short), 7);
save_to_submit_buf(&p.event->args_buf, &stdin_type, sizeof(unsigned short), 9);

void *stdin_path = get_path_str(__builtin_preserve_access_index(&stdin_file->f_path));
save_str_to_buf(&p.event->args_buf, stdin_path, 8);
save_str_to_buf(&p.event->args_buf, stdin_path, 10);

int kernel_invoked = (get_task_parent_flags(task) & PF_KTHREAD) ? 1 : 0;
save_to_submit_buf(&p.event->args_buf, &kernel_invoked, sizeof(int), 9);
save_to_submit_buf(&p.event->args_buf, &kernel_invoked, sizeof(int), 11);

bpf_tail_call(ctx, &prog_array, tail_call_id);
return -1;
}

statfunc int execute_failed_tail2(struct pt_regs *ctx)
{
program_data_t p = {};
if (!init_tailcall_program_data(&p, ctx))
return -1;

long long argv, envp;
struct pt_regs *regs = get_current_task_pt_regs();

if (p.event->context.syscall == SYSCALL_EXECVE) {
argv = get_syscall_arg2(p.event->task, regs, false);
envp = get_syscall_arg3(p.event->task, regs, false);
} else {
argv = get_syscall_arg3(p.event->task, regs, false);
envp = get_syscall_arg4(p.event->task, regs, false);
}

save_str_arr_to_buf(&p.event->args_buf, (const char *const *) argv, 10); // userspace argv

if (p.config->options & OPT_EXEC_ENV) {
save_str_arr_to_buf(&p.event->args_buf, (const char *const *) envp, 11); // userspace envp
}

int ret = PT_REGS_RC(ctx); // needs to be int
return events_perf_submit(&p, ret);
return events_perf_submit(&p, 0);
}

bool use_security_bprm_creds_for_exec = false;

SEC("kprobe/exec_binprm")
TRACE_ENT_FUNC(exec_binprm, EXEC_BINPRM);

SEC("kretprobe/exec_binprm")
int BPF_KPROBE(trace_ret_exec_binprm)
int BPF_KPROBE(trace_exec_binprm)
{
if (use_security_bprm_creds_for_exec) {
return 0;
}
args_t saved_args;
if (load_args(&saved_args, EXEC_BINPRM) != 0) {
// missed entry or not traced
return 0;
}
del_args(EXEC_BINPRM);

int ret_val = PT_REGS_RC(ctx);
if (ret_val == 0)
return 0; // not interested of successful execution - for that we have sched_process_exec

program_data_t p = {};
if (!init_program_data(&p, ctx, PROCESS_EXECUTION_FAILED))
if (!init_program_data(&p, ctx, PROCESS_EXECUTE_FAILED_INTERNAL))
return 0;
return submit_process_execute_failed(ctx, &p);
}

SEC("kretprobe/trace_execute_failed1")
int BPF_KPROBE(trace_execute_failed1)
{
return execute_failed_tail1(ctx, TAIL_PROCESS_EXECUTE_FAILED2);
}

SEC("kretprobe/trace_execute_failed2")
int BPF_KPROBE(trace_execute_failed2)
{
return execute_failed_tail2(ctx);
}

SEC("kprobe/security_bprm_creds_for_exec")
int BPF_KPROBE(trace_security_bprm_creds_for_exec)
{
use_security_bprm_creds_for_exec = true;
program_data_t p = {};
if (!init_program_data(&p, ctx, SECURITY_BPRM_CREDS_FOR_EXEC))
if (!init_program_data(&p, ctx, PROCESS_EXECUTE_FAILED_INTERNAL))
return 0;
return submit_process_execute_failed(ctx, &p);
}
Expand All @@ -5073,6 +5021,34 @@ int BPF_KPROBE(trace_execute_finished)
if (!evaluate_scope_filters(&p))
return 0;

// We can enrich the event with user provided arguments. If we have kernelspace arguments,
// the userspace arguments will be discarded.
struct pt_regs *task_regs = get_current_task_pt_regs();
u64 argv, envp;
void *path;

if (p.event->context.syscall == SYSCALL_EXECVEAT) {
int dirfd = get_syscall_arg1(p.event->task, task_regs, false);
path = (void *) get_syscall_arg2(p.event->task, task_regs, false);
argv = get_syscall_arg3(p.event->task, task_regs, false);
envp = get_syscall_arg4(p.event->task, task_regs, false);
int flags = get_syscall_arg5(p.event->task, task_regs, false);

// send args unique to execevat
save_to_submit_buf(&p.event->args_buf, &dirfd, sizeof(int), 0);
save_to_submit_buf(&p.event->args_buf, &flags, sizeof(int), 1);
} else {
path = (void *) get_syscall_arg1(p.event->task, task_regs, false);
argv = get_syscall_arg2(p.event->task, task_regs, false);
envp = get_syscall_arg3(p.event->task, task_regs, false);
}

save_str_to_buf(&p.event->args_buf, path, 2);
save_str_arr_to_buf(&p.event->args_buf, (const char *const *) argv, 12);
if (p.config->options & OPT_EXEC_ENV) {
save_str_arr_to_buf(&p.event->args_buf, (const char *const *) envp, 13);
}

long exec_ret = PT_REGS_RC(ctx);
return events_perf_submit(&p, exec_ret);
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/ebpf/c/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,14 @@ enum event_id_e
FILE_MODIFICATION,
INOTIFY_WATCH,
SECURITY_BPF_PROG,
PROCESS_EXECUTION_FAILED,
PROCESS_EXECUTE_FAILED,
SECURITY_PATH_NOTIFY,
SET_FS_PWD,
HIDDEN_KERNEL_MODULE_SEEKER,
MODULE_LOAD,
MODULE_FREE,
EXECUTE_FINISHED,
SECURITY_BPRM_CREDS_FOR_EXEC,
PROCESS_EXECUTE_FAILED_INTERNAL,
SECURITY_TASK_SETRLIMIT,
SECURITY_SETTIME64,
MAX_EVENT_ID,
Expand Down
Loading
Loading