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

update(driver): handle processes sending open file descriptors via SCM_RIGHTS #1400

Merged
merged 10 commits into from Oct 13, 2023
Merged
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
@@ -1 +1 @@
2.11.1
2.12.1
78 changes: 45 additions & 33 deletions driver/bpf/fillers.h
Expand Up @@ -4187,6 +4187,10 @@ FILLER(sys_recvmsg_x, true)
CHECK_RES(res);

/* Parameter 4: tuple (type: PT_SOCKTUPLE) */
res = bpf_push_empty_param(data);
CHECK_RES(res);

/* Parameter 5: msg_control (type: PT_BYTEBUF) */
return bpf_push_empty_param(data);
}

Expand Down Expand Up @@ -4225,49 +4229,57 @@ FILLER(sys_recvmsg_x_2, true)
retval = bpf_syscall_get_retval(data->ctx);

/*
* tuple
* tuple and msg_control
*/
if (retval >= 0) {
/*
* Retrieve the message header
*/
val = bpf_syscall_get_argument(data, 1);
if (bpf_probe_read_user(&mh, sizeof(mh), (void *)val))
return PPM_FAILURE_INVALID_USER_MEMORY;

/*
* Get the address
*/
usrsockaddr = (struct sockaddr *)mh.msg_name;
addrlen = mh.msg_namelen;
/*
* Retrieve the message header
*/
val = bpf_syscall_get_argument(data, 1);
if (bpf_probe_read_user(&mh, sizeof(mh), (void *)val))
return PPM_FAILURE_INVALID_USER_MEMORY;

if (usrsockaddr && addrlen != 0) {
/*
* Copy the address
*/
res = bpf_addr_to_kernel(usrsockaddr,
addrlen,
(struct sockaddr *)data->tmp_scratch);
/*
* Get the address
*/
usrsockaddr = (struct sockaddr *)mh.msg_name;
addrlen = mh.msg_namelen;

if (res >= 0) {
fd = bpf_syscall_get_argument(data, 0);
if (usrsockaddr && addrlen != 0) {
/*
* Copy the address
*/
res = bpf_addr_to_kernel(usrsockaddr,
addrlen,
(struct sockaddr *)data->tmp_scratch);

/*
* Convert the fd into socket endpoint information
*/
size = bpf_fd_to_socktuple(data,
fd,
(struct sockaddr *)data->tmp_scratch,
addrlen,
true,
true,
data->tmp_scratch + sizeof(struct sockaddr_storage));
}
if (res >= 0) {
fd = bpf_syscall_get_argument(data, 0);

/*
* Convert the fd into socket endpoint information
*/
size = bpf_fd_to_socktuple(data,
fd,
(struct sockaddr *)data->tmp_scratch,
addrlen,
true,
true,
data->tmp_scratch + sizeof(struct sockaddr_storage));
}
}

data->curarg_already_on_frame = true;
res = __bpf_val_to_ring(data, 0, size, PT_SOCKTUPLE, -1, false, KERNEL);
CHECK_RES(res);

if(mh.msg_control != NULL)
{
res = __bpf_val_to_ring(data, (unsigned long)mh.msg_control, mh.msg_controllen, PT_BYTEBUF, -1, false, USER);
} else
{
res = bpf_push_empty_param(data);
}

return res;
}
Expand Down
2 changes: 1 addition & 1 deletion driver/event_table.c
Expand Up @@ -101,7 +101,7 @@ const struct ppm_event_info g_event_info[] = {
[PPME_SOCKET_SENDMMSG_E] = {"sendmmsg", EC_IO_WRITE | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_SENDMMSG_X] = {"sendmmsg", EC_IO_WRITE | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_RECVMSG_E] = {"recvmsg", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } },
[PPME_SOCKET_RECVMSG_X] = {"recvmsg", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}, {"tuple", PT_SOCKTUPLE, PF_NA} } },
[PPME_SOCKET_RECVMSG_X] = {"recvmsg", EC_IO_READ | EC_SYSCALL, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 5, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"msgcontrol", PT_BYTEBUF, PF_NA} } },
[PPME_SOCKET_RECVMMSG_E] = {"recvmmsg", EC_IO_READ | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_RECVMMSG_X] = {"recvmmsg", EC_IO_READ | EC_SYSCALL, EF_NONE, 0},
[PPME_SOCKET_ACCEPT4_E] = {"accept", EC_NET | EC_SYSCALL, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } },
Expand Down
7 changes: 5 additions & 2 deletions driver/modern_bpf/helpers/store/auxmap_store_params.h
Expand Up @@ -945,8 +945,10 @@ static __always_inline void auxmap__store_msghdr_size_param(struct auxiliary_map
* @param auxmap pointer to the auxmap in which we are storing the param.
* @param msghdr_pointer pointer to `user_msghdr` struct.
* @param len_to_read imposed snaplen.
*
* @return the `user_msghdr` struct that has been read.
*/
static __always_inline void auxmap__store_msghdr_data_param(struct auxiliary_map *auxmap, unsigned long msghdr_pointer, unsigned long len_to_read)
static __always_inline struct user_msghdr auxmap__store_msghdr_data_param(struct auxiliary_map *auxmap, unsigned long msghdr_pointer, unsigned long len_to_read)
{
/* Read the usr_msghdr struct into the stack, if we fail,
* we return an empty param.
Expand All @@ -956,10 +958,11 @@ static __always_inline void auxmap__store_msghdr_data_param(struct auxiliary_map
{
/* in case of NULL msghdr we return an empty param */
push__param_len(auxmap->data, &auxmap->lengths_pos, 0);
return;
return msghdr;
}

auxmap__store_iovec_data_param(auxmap, (unsigned long)msghdr.msg_iov, msghdr.msg_iovlen, len_to_read);
return msghdr;
}

/**
Expand Down
Expand Up @@ -89,11 +89,19 @@ int BPF_PROG(recvmsg_x,

/* Parameter 3: data (type: PT_BYTEBUF) */
unsigned long msghdr_pointer = args[1];
auxmap__store_msghdr_data_param(auxmap, msghdr_pointer, snaplen);
struct user_msghdr msghhdr = auxmap__store_msghdr_data_param(auxmap, msghdr_pointer, snaplen);

/* Parameter 4: tuple (type: PT_SOCKTUPLE) */
u32 socket_fd = (u32)args[0];
auxmap__store_socktuple_param(auxmap, socket_fd, INBOUND);

/* Parameter 5: msg_control (type: PT_BYTEBUF) */
if (msghhdr.msg_control != NULL)
{
auxmap__store_bytebuf_param(auxmap, (unsigned long)msghhdr.msg_control, msghhdr.msg_controllen, USER);
} else {
auxmap__store_empty_param(auxmap);
}
}
else
{
Expand All @@ -105,6 +113,9 @@ int BPF_PROG(recvmsg_x,

/* Parameter 4: tuple (type: PT_SOCKTUPLE) */
auxmap__store_empty_param(auxmap);

/* Parameter 5: msg_control (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);
}

/*=============================== COLLECT PARAMETERS ===========================*/
Expand Down
20 changes: 20 additions & 0 deletions driver/ppm_fillers.c
Expand Up @@ -2878,6 +2878,10 @@ int f_sys_recvmsg_x(struct event_filler_arguments *args)
res = push_empty_param(args);
CHECK_RES(res);

/* Parameter 5: msg_control (type: PT_BYTEBUF) */
res = push_empty_param(args);
CHECK_RES(res);

return add_sentinel(args);
}

Expand Down Expand Up @@ -2959,6 +2963,22 @@ int f_sys_recvmsg_x(struct event_filler_arguments *args)
false,
0);
CHECK_RES(res);

/*
msg_control: ancillary data.
*/
if (mh.msg_control != NULL && mh.msg_controllen > 0)
{
res = val_to_ring(args, (uint64_t)mh.msg_control, (uint32_t)mh.msg_controllen, true, 0);
CHECK_RES(res);
}
else
{
/* pushing empty data */
res = push_empty_param(args);
CHECK_RES(res);
}

return add_sentinel(args);
}

Expand Down