Skip to content
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
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.11.0
3.12.0
51 changes: 33 additions & 18 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,45 +1214,60 @@ FILLER(sys_connect_x, true) {
}

FILLER(sys_socketpair_x, true) {
struct unix_sock *us = NULL;
struct sock *speer = NULL;
/* Parameter 1: res (type: PT_ERRNO) */
long retval = bpf_syscall_get_retval(data->ctx);
int res = bpf_push_s64_to_ring(data, retval);
CHECK_RES(res);

/* In case of failure we send invalid fd (-1) */
int fds[2] = {-1, -1};
unsigned long val;
long retval;
int res;

/* ret */
retval = bpf_syscall_get_retval(data->ctx);
res = bpf_push_s64_to_ring(data, retval);
CHECK_RES(res);
struct unix_sock *us = NULL;
struct sock *speer = NULL;

if(retval == 0) {
val = bpf_syscall_get_argument(data, 3);
if(bpf_probe_read_user(fds, 2 * sizeof(int), (void *)val))
void *val = (void *)bpf_syscall_get_argument(data, 3);
if(bpf_probe_read_user(fds, 2 * sizeof(int), val)) {
return PPM_FAILURE_INVALID_USER_MEMORY;
}

struct socket *sock = bpf_sockfd_lookup(data, fds[0]);

if(sock) {
us = (struct unix_sock *)_READ(sock->sk);
speer = _READ(us->peer);
}
}
/* fd1 */
/* Parameter 2: fd1 (type: PT_FD) */
res = bpf_push_s64_to_ring(data, (int64_t)fds[0]);
CHECK_RES(res);

/* fd2 */
/* Parameter 3: fd2 (type: PT_FD) */
res = bpf_push_s64_to_ring(data, (int64_t)fds[1]);
CHECK_RES(res);

/* source */
/* Parameter 4: source (type: PT_UINT64) */
res = bpf_push_u64_to_ring(data, (unsigned long)us);
CHECK_RES(res);

/* peer */
return bpf_push_u64_to_ring(data, (unsigned long)speer);
/* Parameter 5: peer (type: PT_UINT64) */
bpf_push_u64_to_ring(data, (unsigned long)speer);
CHECK_RES(res);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
/* why to send 32 bits if we need only 8 bits? */
uint8_t domain = (uint8_t)bpf_syscall_get_argument(data, 0);
res = bpf_push_u32_to_ring(data, domain);
CHECK_RES(res);

/* Parameter 7: type (type: PT_UINT32) */
/* this should be an int, not an uint32 */
uint32_t type = (uint32_t)bpf_syscall_get_argument(data, 1);
res = bpf_push_u32_to_ring(data, type);
CHECK_RES(res);

/* Parameter 8: proto (type: PT_UINT32) */
/* this should be an int, not an uint32 */
uint32_t proto = (uint32_t)bpf_syscall_get_argument(data, 2);
return bpf_push_u32_to_ring(data, proto);
}

// TODO bpf_val_to_ring_dyn?
Expand Down
11 changes: 7 additions & 4 deletions driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,20 +298,23 @@ const struct ppm_event_info g_event_info[] = {
[PPME_SOCKET_GETPEERNAME_X] = {"getpeername", EC_NET | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_SOCKETPAIR_E] = {"socketpair",
EC_IPC | EC_SYSCALL,
EF_CREATES_FD | EF_MODIFIES_STATE,
EF_CREATES_FD | EF_MODIFIES_STATE | EF_TMP_CONVERTER_MANAGED,
3,
{{"domain", PT_ENUMFLAGS32, PF_DEC, socket_families},
{"type", PT_UINT32, PF_DEC},
{"proto", PT_UINT32, PF_DEC}}},
[PPME_SOCKET_SOCKETPAIR_X] = {"socketpair",
EC_IPC | EC_SYSCALL,
EF_CREATES_FD | EF_MODIFIES_STATE,
5,
EF_CREATES_FD | EF_MODIFIES_STATE | EF_TMP_CONVERTER_MANAGED,
8,
{{"res", PT_ERRNO, PF_DEC},
{"fd1", PT_FD, PF_DEC},
{"fd2", PT_FD, PF_DEC},
{"source", PT_UINT64, PF_HEX},
{"peer", PT_UINT64, PF_HEX}}},
{"peer", PT_UINT64, PF_HEX},
{"domain", PT_ENUMFLAGS32, PF_DEC, socket_families},
{"type", PT_UINT32, PF_DEC},
{"proto", PT_UINT32, PF_DEC}}},
[PPME_SOCKET_SETSOCKOPT_E] = {"setsockopt", EC_NET | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_SETSOCKOPT_X] =
{"setsockopt",
Expand Down
2 changes: 1 addition & 1 deletion driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#define GETPEERNAME_E_SIZE HEADER_LEN
#define GETPEERNAME_X_SIZE HEADER_LEN
#define SOCKETPAIR_E_SIZE HEADER_LEN + sizeof(uint32_t) * 3 + PARAM_LEN * 3
#define SOCKETPAIR_X_SIZE HEADER_LEN + sizeof(int64_t) * 3 + sizeof(uint64_t) * 2 + PARAM_LEN * 5
#define SOCKETPAIR_X_SIZE HEADER_LEN + sizeof(int64_t) * 3 + sizeof(uint32_t) * 3 + sizeof(uint64_t) * 2 + PARAM_LEN * 8
#define SETSOCKOPT_E_SIZE HEADER_LEN
#define GETSOCKOPT_E_SIZE HEADER_LEN
#define SENDMMSG_E_SIZE HEADER_LEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ int BPF_PROG(socketpair_e, struct pt_regs *regs, long id) {
/*=============================== COLLECT PARAMETERS ===========================*/

/* Parameter 1: domain (type: PT_ENUMFLAGS32) */
/* why to send 32 bits if we need only 8 bits? */
/* Why to send 32 bits if we need only 8 bits? */
uint8_t domain = (uint8_t)args[0];
ringbuf__store_u32(&ringbuf, (uint32_t)socket_family_to_scap(domain));

/* Parameter 2: type (type: PT_UINT32) */
/* this should be an int, not a uint32 */
/* This should be an int, not an uint32. */
uint32_t type = (uint32_t)args[1];
ringbuf__store_u32(&ringbuf, type);

/* Parameter 3: proto (type: PT_UINT32) */
/* this should be an int, not a uint32 */
/* This should be an int, not an uint32. */
uint32_t proto = (uint32_t)args[2];
ringbuf__store_u32(&ringbuf, proto);

Expand All @@ -55,6 +55,12 @@ int BPF_PROG(socketpair_e, struct pt_regs *regs, long id) {

SEC("tp_btf/sys_exit")
int BPF_PROG(socketpair_x, struct pt_regs *regs, long ret) {
/* We need to keep this at the beginning of the program because otherwise we alter the state of
* the ebpf registers causing a verifier issue.
*/
unsigned long args[4] = {0};
extract__network_args(args, 4, regs);

struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, SOCKETPAIR_X_SIZE, PPME_SOCKET_SOCKETPAIR_X)) {
return 0;
Expand All @@ -68,18 +74,13 @@ int BPF_PROG(socketpair_x, struct pt_regs *regs, long ret) {
ringbuf__store_s64(&ringbuf, ret);

int32_t fds[2] = {-1, -1};
unsigned long source = 0;
unsigned long peer = 0;
unsigned long fds_pointer = 0;
uint64_t source = 0;
uint64_t peer = 0;

/* In case of success we have 0. */
if(ret == 0) {
/* Collect parameters at the beginning to manage socketcalls */
unsigned long args[4] = {0};
extract__network_args(args, 4, regs);

/* Get new sockets. */
fds_pointer = args[3];
void *fds_pointer = (void *)args[3];
bpf_probe_read_user((void *)fds, 2 * sizeof(int32_t), (void *)fds_pointer);

/* Get source and peer. */
Expand All @@ -104,6 +105,21 @@ int BPF_PROG(socketpair_x, struct pt_regs *regs, long ret) {
/* Parameter 5: peer (type: PT_UINT64) */
ringbuf__store_u64(&ringbuf, peer);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
/* Why to send 32 bits if we need only 8 bits? */
uint8_t domain = (uint8_t)args[0];
ringbuf__store_u32(&ringbuf, (uint32_t)socket_family_to_scap(domain));

/* Parameter 7: type (type: PT_UINT32) */
/* This should be an int, not an uint32. */
uint32_t type = (uint32_t)args[1];
ringbuf__store_u32(&ringbuf, type);

/* Parameter 8: proto (type: PT_UINT32) */
/* This should be an int, not an uint32. */
uint32_t proto = (uint32_t)args[2];
ringbuf__store_u32(&ringbuf, proto);

/*=============================== COLLECT PARAMETERS ===========================*/

ringbuf__submit_event(&ringbuf);
Expand Down
31 changes: 21 additions & 10 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,20 +1815,14 @@ int f_sys_socketpair_x(struct event_filler_arguments *args) {
struct unix_sock *us;
struct sock *speer;

/*
* retval
*/
/* Parameter 1: res (type: PT_ERRNO) */
retval = (int64_t)syscall_get_return_value(current, args->regs);
res = val_to_ring(args, retval, 0, false, 0);
CHECK_RES(res);

/*
* If the call was successful, copy the FDs
*/
/* In case of success we have 0. */
if(likely(retval == 0)) {
/*
* fds
*/
/* Get new sockets file descriptors. */
syscall_get_arguments_deprecated(args, 3, 1, &val);
#ifdef CONFIG_COMPAT
if(!args->compat) {
Expand All @@ -1842,13 +1836,15 @@ int f_sys_socketpair_x(struct event_filler_arguments *args) {
}
#endif

/* Parameter 2: fd1 (type: PT_FD) */
res = val_to_ring(args, (int64_t)fds[0], 0, false, 0);
CHECK_RES(res);

/* Parameter 3: fd2 (type: PT_FD) */
res = val_to_ring(args, (int64_t)fds[1], 0, false, 0);
CHECK_RES(res);

/* get socket source and peer address */
/* Get socket source and peer address. */
sock = sockfd_lookup(fds[0], &err);
if(likely(sock != NULL)) {
us = unix_sk(sock->sk);
Expand Down Expand Up @@ -1883,6 +1879,21 @@ int f_sys_socketpair_x(struct event_filler_arguments *args) {
CHECK_RES(res);
}

/* Parameter 2: domain (type: PT_ENUMFLAGS32) */
syscall_get_arguments_deprecated(args, 0, 1, &val);
res = val_to_ring(args, val, 0, true, 0);
CHECK_RES(res);

/* Parameter 3: type (type: PT_UINT32) */
syscall_get_arguments_deprecated(args, 1, 1, &val);
res = val_to_ring(args, val, 0, true, 0);
CHECK_RES(res);

/* Parameter 4: proto (type: PT_UINT32) */
syscall_get_arguments_deprecated(args, 2, 1, &val);
res = val_to_ring(args, val, 0, true, 0);
CHECK_RES(res);

return add_sentinel(args);
}

Expand Down
32 changes: 25 additions & 7 deletions test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1325,26 +1325,35 @@ TEST(SyscallExit, socketcall_socketpairX_success) {

/*=============================== ASSERT PARAMETERS ===========================*/

/* Parameter 1: res (type: PT_ERRNO)*/
/* Parameter 1: res (type: PT_ERRNO) */
evt_test->assert_numeric_param(1, (int64_t)0);

/* Parameter 2: fd1 (type: PT_FD)*/
/* Parameter 2: fd1 (type: PT_FD) */
evt_test->assert_numeric_param(2, (int64_t)fd[0]);

/* Parameter 3: fd2 (type: PT_FD)*/
/* Parameter 3: fd2 (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)fd[1]);

/* Parameter 4: source (type: PT_UINT64)*/
/* Parameter 4: source (type: PT_UINT64) */
/* Here we have a kernel pointer, we don't know the exact value. */
evt_test->assert_numeric_param(4, (uint64_t)0, NOT_EQUAL);

/* Parameter 5: peer (type: PT_UINT64)*/
/* Parameter 5: peer (type: PT_UINT64) */
/* Here we have a kernel pointer, we don't know the exact value. */
evt_test->assert_numeric_param(5, (uint64_t)0, NOT_EQUAL);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
evt_test->assert_numeric_param(6, (uint32_t)PPM_AF_LOCAL);

/* Parameter 7: type (type: PT_UINT32) */
evt_test->assert_numeric_param(7, (uint32_t)type);

/* Parameter 8: proto (type: PT_UINT32) */
evt_test->assert_numeric_param(8, (uint32_t)protocol);

/*=============================== ASSERT PARAMETERS ===========================*/

evt_test->assert_num_params_pushed(5);
evt_test->assert_num_params_pushed(8);
}

TEST(SyscallExit, socketcall_socketpairX_failure) {
Expand Down Expand Up @@ -1400,9 +1409,18 @@ TEST(SyscallExit, socketcall_socketpairX_failure) {
/* Parameter 5: peer (type: PT_UINT64) */
evt_test->assert_numeric_param(5, (uint64_t)0);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
evt_test->assert_numeric_param(6, (uint32_t)PPM_AF_LOCAL);

/* Parameter 7: type (type: PT_UINT32) */
evt_test->assert_numeric_param(7, (uint32_t)type);

/* Parameter 8: proto (type: PT_UINT32) */
evt_test->assert_numeric_param(8, (uint32_t)protocol);

/*=============================== ASSERT PARAMETERS ===========================*/

evt_test->assert_num_params_pushed(5);
evt_test->assert_num_params_pushed(8);
}

#endif
Expand Down
32 changes: 25 additions & 7 deletions test/drivers/test_suites/syscall_exit_suite/socketpair_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,35 @@ TEST(SyscallExit, socketpairX_success) {

/*=============================== ASSERT PARAMETERS ===========================*/

/* Parameter 1: res (type: PT_ERRNO)*/
/* Parameter 1: res (type: PT_ERRNO) */
evt_test->assert_numeric_param(1, (int64_t)0);

/* Parameter 2: fd1 (type: PT_FD)*/
/* Parameter 2: fd1 (type: PT_FD) */
evt_test->assert_numeric_param(2, (int64_t)fd[0]);

/* Parameter 3: fd2 (type: PT_FD)*/
/* Parameter 3: fd2 (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)fd[1]);

/* Parameter 4: source (type: PT_UINT64)*/
/* Parameter 4: source (type: PT_UINT64) */
/* Here we have a kernel pointer, we don't know the exact value. */
evt_test->assert_numeric_param(4, (uint64_t)0, NOT_EQUAL);

/* Parameter 5: peer (type: PT_UINT64)*/
/* Parameter 5: peer (type: PT_UINT64) */
/* Here we have a kernel pointer, we don't know the exact value. */
evt_test->assert_numeric_param(5, (uint64_t)0, NOT_EQUAL);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
evt_test->assert_numeric_param(6, (uint32_t)PPM_AF_LOCAL);

/* Parameter 7: type (type: PT_UINT32) */
evt_test->assert_numeric_param(7, (uint32_t)type);

/* Parameter 8: proto (type: PT_UINT32) */
evt_test->assert_numeric_param(8, (uint32_t)protocol);

/*=============================== ASSERT PARAMETERS ===========================*/

evt_test->assert_num_params_pushed(5);
evt_test->assert_num_params_pushed(8);
}

TEST(SyscallExit, socketpairX_failure) {
Expand Down Expand Up @@ -108,9 +117,18 @@ TEST(SyscallExit, socketpairX_failure) {
/* Parameter 5: peer (type: PT_UINT64) */
evt_test->assert_numeric_param(5, (uint64_t)0);

/* Parameter 6: domain (type: PT_ENUMFLAGS32) */
evt_test->assert_numeric_param(6, (uint32_t)PPM_AF_LOCAL);

/* Parameter 7: type (type: PT_UINT32) */
evt_test->assert_numeric_param(7, (uint32_t)type);

/* Parameter 8: proto (type: PT_UINT32) */
evt_test->assert_numeric_param(8, (uint32_t)protocol);

/*=============================== ASSERT PARAMETERS ===========================*/

evt_test->assert_num_params_pushed(5);
evt_test->assert_num_params_pushed(8);
}

#endif
Loading
Loading