From b138bf7eea074042d1a782a7feee9b148cdb69c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Geyslan=20Greg=C3=B3rio?= Date: Thu, 23 Nov 2023 10:36:37 -0300 Subject: [PATCH] fix(ebpf): handle 32-bit socketcall syscall Depending on the kernel version, 32-bit binaries use either the socketcall syscall as a entry point for socket syscalls functions, or the individual syscalls (socket, bind, connect, etc). Context: #3676 --- pkg/ebpf/c/common/arch.h | 2 ++ pkg/ebpf/c/tracee.bpf.c | 69 ++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/pkg/ebpf/c/common/arch.h b/pkg/ebpf/c/common/arch.h index 403bb2dd6e33..9ce0f147dfdf 100644 --- a/pkg/ebpf/c/common/arch.h +++ b/pkg/ebpf/c/common/arch.h @@ -181,6 +181,8 @@ statfunc struct pt_regs *get_task_pt_regs(struct task_struct *task) #define SYSCALL_LANDLOCK_RESTRICT_SELF 446 #define SYSCALL_PROCESS_MRELEASE 448 + #define SYSCALL_SOCKETCALL 473 // x86 only + #elif defined(bpf_target_arm64) #define SYSCALL_READ 63 #define SYSCALL_WRITE 64 diff --git a/pkg/ebpf/c/tracee.bpf.c b/pkg/ebpf/c/tracee.bpf.c index 4fc547406d1a..943b40d46e2d 100644 --- a/pkg/ebpf/c/tracee.bpf.c +++ b/pkg/ebpf/c/tracee.bpf.c @@ -2455,10 +2455,20 @@ int BPF_KPROBE(trace_security_socket_listen) // Load the arguments given to the listen syscall (which eventually invokes this function) syscall_data_t *sys = &p.task_info->syscall_data; - if (!p.task_info->syscall_traced || sys->id != SYSCALL_LISTEN) + if (!p.task_info->syscall_traced) return 0; - save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + switch (sys->id) { + case SYSCALL_LISTEN: + save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + break; + case SYSCALL_SOCKETCALL: + save_to_submit_buf(&p.event->args_buf, (void *) sys->args.args[1], sizeof(u32), 0); + break; + default: + return 0; + } + save_sockaddr_to_buf(&p.event->args_buf, sock, 1); save_to_submit_buf(&p.event->args_buf, (void *) &backlog, sizeof(int), 2); @@ -2490,10 +2500,19 @@ int BPF_KPROBE(trace_security_socket_connect) // Load the arguments given to the connect syscall (which eventually invokes this function) syscall_data_t *sys = &p.task_info->syscall_data; - if (!p.task_info->syscall_traced || sys->id != SYSCALL_CONNECT) + if (!p.task_info->syscall_traced) return 0; - save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + switch (sys->id) { + case SYSCALL_CONNECT: + save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + break; + case SYSCALL_SOCKETCALL: + save_to_submit_buf(&p.event->args_buf, (void *) sys->args.args[1], sizeof(u32), 0); + break; + default: + return 0; + } if (sa_fam == AF_INET) { save_to_submit_buf(&p.event->args_buf, (void *) address, sizeof(struct sockaddr_in), 1); @@ -2541,10 +2560,21 @@ int BPF_KPROBE(trace_security_socket_accept) return 0; // Load the arguments given to the accept syscall (which eventually invokes this function) - if (!p.task_info->syscall_traced || (sys->id != SYSCALL_ACCEPT && sys->id != SYSCALL_ACCEPT4)) + if (!p.task_info->syscall_traced) return 0; - save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + switch (sys->id) { + case SYSCALL_ACCEPT: + case SYSCALL_ACCEPT4: + save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + break; + case SYSCALL_SOCKETCALL: + save_to_submit_buf(&p.event->args_buf, (void *) sys->args.args[1], sizeof(u32), 0); + break; + default: + return 0; + } + save_sockaddr_to_buf(&p.event->args_buf, sock, 1); return events_perf_submit(&p, SECURITY_SOCKET_ACCEPT, 0); @@ -2578,10 +2608,19 @@ int BPF_KPROBE(trace_security_socket_bind) // Load the arguments given to the bind syscall (which eventually invokes this function) syscall_data_t *sys = &p.task_info->syscall_data; - if (!p.task_info->syscall_traced || sys->id != SYSCALL_BIND) + if (!p.task_info->syscall_traced) return 0; - save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + switch (sys->id) { + case SYSCALL_BIND: + save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + break; + case SYSCALL_SOCKETCALL: + save_to_submit_buf(&p.event->args_buf, (void *) sys->args.args[1], sizeof(u32), 0); + break; + default: + return 0; + } u16 protocol = get_sock_protocol(sk); net_id_t connect_id = {0}; @@ -2644,10 +2683,20 @@ int BPF_KPROBE(trace_security_socket_setsockopt) return -1; } - if (!p.task_info->syscall_traced || sys->id != SYSCALL_SETSOCKOPT) + if (!p.task_info->syscall_traced) return 0; - save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + switch (sys->id) { + case SYSCALL_SETSOCKOPT: + save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[0], sizeof(u32), 0); + break; + case SYSCALL_SOCKETCALL: + save_to_submit_buf(&p.event->args_buf, (void *) sys->args.args[1], sizeof(u32), 0); + break; + default: + return 0; + } + save_to_submit_buf(&p.event->args_buf, (void *) &level, sizeof(int), 1); save_to_submit_buf(&p.event->args_buf, (void *) &optname, sizeof(int), 2); save_sockaddr_to_buf(&p.event->args_buf, sock, 3);