Skip to content

Commit

Permalink
fix(ebpf): handle 32-bit socketcall syscall
Browse files Browse the repository at this point in the history
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
  • Loading branch information
geyslan committed Nov 23, 2023
1 parent 6de91ac commit b138bf7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
2 changes: 2 additions & 0 deletions pkg/ebpf/c/common/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
69 changes: 59 additions & 10 deletions pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit b138bf7

Please sign in to comment.