Skip to content

Commit d925955

Browse files
committed
feat: add RECVFROM_E params to RECVFROM_X
Add enter events parameters to `RECVFROM_X` event definition and align all three kernel drivers to the new definition. Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
1 parent 6c7ef20 commit d925955

File tree

16 files changed

+492
-235
lines changed

16 files changed

+492
-235
lines changed

driver/SCHEMA_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.9.0
1+
3.10.0

driver/bpf/fillers.h

Lines changed: 76 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -4073,42 +4073,6 @@ FILLER(sys_socket_bind_x, true) {
40734073
return bpf_push_s64_to_ring(data, (int64_t)fd);
40744074
}
40754075

4076-
static __always_inline int f_sys_recv_x_common(struct filler_data *data, long retval) {
4077-
unsigned long bufsize;
4078-
unsigned long val;
4079-
int res;
4080-
4081-
/*
4082-
* res
4083-
*/
4084-
res = bpf_push_s64_to_ring(data, retval);
4085-
CHECK_RES(res);
4086-
4087-
/*
4088-
* data
4089-
*/
4090-
if(retval < 0) {
4091-
/*
4092-
* The operation failed, return an empty buffer
4093-
*/
4094-
val = 0;
4095-
bufsize = 0;
4096-
} else {
4097-
val = bpf_syscall_get_argument(data, 1);
4098-
4099-
/*
4100-
* The return value can be lower than the value provided by the user,
4101-
* and we take that into account.
4102-
*/
4103-
bufsize = retval;
4104-
}
4105-
4106-
data->fd = bpf_syscall_get_argument(data, 0);
4107-
res = __bpf_val_to_ring(data, val, bufsize, PT_BYTEBUF, -1, true, USER);
4108-
4109-
return res;
4110-
}
4111-
41124076
FILLER(sys_recv_x, true) {
41134077
/* Parameter 1: res (type: PT_ERRNO) */
41144078
long retval = bpf_syscall_get_retval(data->ctx);
@@ -4162,8 +4126,8 @@ FILLER(sys_recv_x, true) {
41624126

41634127
FILLER(sys_recvfrom_e, true) {
41644128
/* Parameter 1: fd (type: PT_FD) */
4165-
int32_t fd = (int32_t)bpf_syscall_get_argument(data, 0);
4166-
int res = bpf_push_s64_to_ring(data, (int64_t)fd);
4129+
int64_t fd = (int32_t)bpf_syscall_get_argument(data, 0);
4130+
int res = bpf_push_s64_to_ring(data, fd);
41674131
CHECK_RES(res);
41684132

41694133
/* Parameter 2: size (type: PT_UINT32) */
@@ -4172,79 +4136,92 @@ FILLER(sys_recvfrom_e, true) {
41724136
}
41734137

41744138
FILLER(sys_recvfrom_x, true) {
4175-
struct sockaddr *usrsockaddr;
4176-
unsigned long val;
4177-
uint16_t size = 0;
4178-
long retval;
4179-
int addrlen = 0;
4180-
int err = 0;
4181-
int res;
4182-
int fd;
4183-
bool push = true;
4184-
bool from_usr = false;
4185-
4186-
/*
4187-
* Push the common params to the ring
4188-
*/
4189-
retval = bpf_syscall_get_retval(data->ctx);
4190-
res = f_sys_recv_x_common(data, retval);
4139+
/* Parameter 1: res (type: PT_ERRNO) */
4140+
long retval = bpf_syscall_get_retval(data->ctx);
4141+
int res = bpf_push_s64_to_ring(data, retval);
41914142
CHECK_RES(res);
41924143

4193-
if(retval >= 0) {
4194-
/*
4195-
* Get the fd
4196-
*/
4197-
fd = bpf_syscall_get_argument(data, 0);
4144+
/* Extract fd and size parameters */
4145+
int64_t fd = (int64_t)(int32_t)bpf_syscall_get_argument(data, 0);
4146+
uint32_t size = (uint32_t)bpf_syscall_get_argument(data, 2);
41984147

4199-
/*
4200-
* Get the address
4201-
*/
4202-
usrsockaddr = (struct sockaddr *)bpf_syscall_get_argument(data, 4);
4148+
if(retval < 0) {
4149+
/* Parameter 2: data (type: PT_BYTEBUF) */
4150+
bpf_push_empty_param(data);
42034151

4204-
/*
4205-
* Get the address len
4206-
*/
4207-
val = bpf_syscall_get_argument(data, 5);
4152+
/* Parameter 3: tuple (type: PT_SOCKTUPLE) */
4153+
bpf_push_empty_param(data);
42084154

4209-
if(usrsockaddr && val != 0) {
4210-
if(bpf_probe_read_user(&addrlen, sizeof(addrlen), (void *)val))
4211-
return PPM_FAILURE_INVALID_USER_MEMORY;
4155+
/* Parameter 4: fd (type: PT_FD) */
4156+
res = bpf_push_s64_to_ring(data, fd);
4157+
CHECK_RES(res);
42124158

4213-
/*
4214-
* Copy the address
4215-
*/
4216-
err = bpf_addr_to_kernel(usrsockaddr, addrlen, (struct sockaddr *)data->tmp_scratch);
4217-
if(err >= 0) {
4218-
/*
4219-
* Convert the fd into socket endpoint information
4220-
*/
4221-
from_usr = true;
4222-
} else {
4223-
// Do not send any socket endpoint info.
4224-
push = false;
4225-
}
4159+
/* Parameter 5: size (type: PT_UINT32) */
4160+
return bpf_push_u32_to_ring(data, size);
4161+
}
4162+
4163+
/* Handle successful system call path. */
4164+
4165+
/* Parameter 2: data (type: PT_BYTEBUF) */
4166+
const unsigned long bytes_to_read = retval;
4167+
const unsigned long received_data_pointer = bpf_syscall_get_argument(data, 1);
4168+
data->fd = fd;
4169+
res = __bpf_val_to_ring(data, received_data_pointer, bytes_to_read, PT_BYTEBUF, -1, true, USER);
4170+
4171+
/* Get the address */
4172+
struct sockaddr __user *usrsockaddr =
4173+
(struct sockaddr __user *)bpf_syscall_get_argument(data, 4);
4174+
4175+
/* Get the address len pointer */
4176+
void *usrsockaddr_len_pointer = (void *)bpf_syscall_get_argument(data, 5);
4177+
4178+
/* Evaluate socktuple, leveraging the user-provided address if possible */
4179+
struct sockaddr *ksockaddr = (struct sockaddr *)data->tmp_scratch;
4180+
bool use_sockaddr_user_data = false;
4181+
bool push_socktuple = true;
4182+
unsigned long usrsockaddr_len = 0;
4183+
if(usrsockaddr != NULL && usrsockaddr_len_pointer != NULL) {
4184+
/* Copy address len into kernel memory */
4185+
if(bpf_probe_read_user(&usrsockaddr_len,
4186+
sizeof(usrsockaddr_len),
4187+
usrsockaddr_len_pointer)) {
4188+
return PPM_FAILURE_INVALID_USER_MEMORY;
42264189
}
4227-
if(push) {
4228-
/*
4229-
* Get socket endpoint information from fd if the user-provided *sockaddr is NULL
4230-
*/
4231-
size = bpf_fd_to_socktuple(data,
4232-
fd,
4233-
(struct sockaddr *)data->tmp_scratch,
4234-
addrlen,
4235-
from_usr,
4236-
true,
4237-
data->tmp_scratch + sizeof(struct sockaddr_storage));
4190+
4191+
/* Copy the address into kernel memory */
4192+
res = bpf_addr_to_kernel(usrsockaddr, usrsockaddr_len, ksockaddr);
4193+
if(likely(res >= 0)) {
4194+
/* Convert the fd into socket endpoint information */
4195+
use_sockaddr_user_data = true;
4196+
} else {
4197+
/* Do not send any socket endpoint information */
4198+
push_socktuple = false;
42384199
}
42394200
}
42404201

4241-
/*
4242-
* Copy the endpoint info into the ring
4243-
*/
4202+
uint32_t socktuple_size = 0;
4203+
if(push_socktuple) {
4204+
/* Convert the fd into socket endpoint information */
4205+
socktuple_size = bpf_fd_to_socktuple(data,
4206+
fd,
4207+
ksockaddr,
4208+
usrsockaddr_len,
4209+
use_sockaddr_user_data,
4210+
true,
4211+
data->tmp_scratch + sizeof(struct sockaddr_storage));
4212+
}
4213+
4214+
/* Parameter 3: tuple (type: PT_SOCKTUPLE) */
42444215
data->curarg_already_on_frame = true;
4245-
res = __bpf_val_to_ring(data, 0, size, PT_SOCKTUPLE, -1, false, KERNEL);
4216+
res = bpf_val_to_ring_len(data, 0, socktuple_size);
4217+
CHECK_RES(res);
42464218

4247-
return res;
4219+
/* Parameter 4: fd (type: PT_FD) */
4220+
res = bpf_push_s64_to_ring(data, fd);
4221+
CHECK_RES(res);
4222+
4223+
/* Parameter 5: size (type: PT_UINT32) */
4224+
return bpf_push_u32_to_ring(data, size);
42484225
}
42494226

42504227
FILLER(sys_shutdown_e, true) {

driver/event_table.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,16 +265,20 @@ const struct ppm_event_info g_event_info[] = {
265265
{"tuple", PT_SOCKTUPLE, PF_NA}}},
266266
[PPME_SOCKET_RECVFROM_E] = {"recvfrom",
267267
EC_IO_READ | EC_SYSCALL,
268-
EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE,
268+
EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE |
269+
EF_TMP_CONVERTER_MANAGED,
269270
2,
270271
{{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}}},
271272
[PPME_SOCKET_RECVFROM_X] = {"recvfrom",
272273
EC_IO_READ | EC_SYSCALL,
273-
EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE,
274-
3,
274+
EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE |
275+
EF_TMP_CONVERTER_MANAGED,
276+
5,
275277
{{"res", PT_ERRNO, PF_DEC},
276278
{"data", PT_BYTEBUF, PF_NA},
277-
{"tuple", PT_SOCKTUPLE, PF_NA}}},
279+
{"tuple", PT_SOCKTUPLE, PF_NA},
280+
{"fd", PT_FD, PF_DEC},
281+
{"size", PT_UINT32, PF_DEC}}},
278282
[PPME_SOCKET_SHUTDOWN_E] = {"shutdown",
279283
EC_NET | EC_SYSCALL,
280284
EF_USES_FD | EF_MODIFIES_STATE,

driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvfrom.bpf.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ int BPF_PROG(recvfrom_e, struct pt_regs *regs, long id) {
2929
/*=============================== COLLECT PARAMETERS ===========================*/
3030

3131
/* Parameter 1: fd (type: PT_FD) */
32-
int32_t socket_fd = (int32_t)args[0];
33-
ringbuf__store_s64(&ringbuf, (int64_t)socket_fd);
32+
int64_t socket_fd = (int32_t)args[0];
33+
ringbuf__store_s64(&ringbuf, socket_fd);
3434

3535
/* Parameter 2: size (type: PT_UINT32) */
3636
uint32_t size = (uint32_t)args[2];
@@ -61,6 +61,12 @@ int BPF_PROG(recvfrom_x, struct pt_regs *regs, long ret) {
6161
/* Parameter 1: res (type: PT_ERRNO) */
6262
auxmap__store_s64_param(auxmap, ret);
6363

64+
/* Collect parameters at the beginning to manage socketcalls */
65+
unsigned long args[5] = {0};
66+
extract__network_args(args, 5, regs);
67+
68+
uint32_t socket_fd = (uint32_t)args[0];
69+
6470
if(ret >= 0) {
6571
/* We read the minimum between `snaplen` and what we really
6672
* have in the buffer.
@@ -75,17 +81,14 @@ int BPF_PROG(recvfrom_x, struct pt_regs *regs, long ret) {
7581
snaplen = ret;
7682
}
7783

78-
/* Collect parameters at the beginning to manage socketcalls */
79-
unsigned long args[5] = {0};
80-
extract__network_args(args, 5, regs);
81-
8284
/* Parameter 2: data (type: PT_BYTEBUF) */
8385
unsigned long received_data_pointer = args[1];
8486
auxmap__store_bytebuf_param(auxmap, received_data_pointer, snaplen, USER);
8587

8688
/* Parameter 3: tuple (type: PT_SOCKTUPLE) */
87-
uint32_t socket_fd = (uint32_t)args[0];
8889
struct sockaddr *usrsockaddr = (struct sockaddr *)args[4];
90+
/* Notice: the following will push an empty parameter if something goes wrong (e.g.: fd not
91+
* valid) */
8992
auxmap__store_socktuple_param(auxmap, socket_fd, INBOUND, usrsockaddr);
9093
} else {
9194
/* Parameter 2: data (type: PT_BYTEBUF) */
@@ -95,6 +98,13 @@ int BPF_PROG(recvfrom_x, struct pt_regs *regs, long ret) {
9598
auxmap__store_empty_param(auxmap);
9699
}
97100

101+
/* Parameter 4: fd (type: PT_FD) */
102+
auxmap__store_s64_param(auxmap, socket_fd);
103+
104+
/* Parameter 5: size (type: PT_UINT32) */
105+
uint32_t size = (uint32_t)args[2];
106+
auxmap__store_u32_param(auxmap, size);
107+
98108
/*=============================== COLLECT PARAMETERS ===========================*/
99109

100110
auxmap__finalize_event_header(auxmap);

0 commit comments

Comments
 (0)