Skip to content

Commit

Permalink
new: extend BIND_X
Browse files Browse the repository at this point in the history
Signed-off-by: Leonardo Di Giovanna <[email protected]>
  • Loading branch information
ekoops committed Dec 17, 2024
1 parent 9ee57c8 commit eedda2e
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 33 deletions.
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.0
3.2.0
14 changes: 7 additions & 7 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -3941,18 +3941,15 @@ FILLER(sys_socket_bind_x, true) {
uint16_t size = 0;
int err = 0;
long retval;
int32_t fd;
int res;

/*
* res
*/
/* Parameter 1: res (type: PT_ERRNO) */
retval = bpf_syscall_get_retval(data->ctx);
res = bpf_push_s64_to_ring(data, retval);
CHECK_RES(res);

/*
* addr
*/
/* Parameter 2: addr (type: PT_SOCKADDR) */
usrsockaddr = (struct sockaddr __user *)bpf_syscall_get_argument(data, 1);
val = bpf_syscall_get_argument(data, 2);

Expand All @@ -3974,8 +3971,11 @@ FILLER(sys_socket_bind_x, true) {
*/
data->curarg_already_on_frame = true;
res = bpf_val_to_ring_len(data, 0, size);
CHECK_RES(res);

return res;
/* Parameter 3: fd (type: PT_FD) */
fd = bpf_syscall_get_argument(data, 0);
return bpf_push_s64_to_ring(data, (int64_t)fd);
}

static __always_inline int f_sys_recv_x_common(struct filler_data *data, long retval) {
Expand Down
10 changes: 6 additions & 4 deletions driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,16 @@ const struct ppm_event_info g_event_info[] = {
{{"fd", PT_FD, PF_DEC}}},
[PPME_SOCKET_BIND_E] = {"bind",
EC_NET | EC_SYSCALL,
EF_USES_FD | EF_MODIFIES_STATE,
EF_USES_FD | EF_MODIFIES_STATE | EF_TMP_CONVERTER_MANAGED,
1,
{{"fd", PT_FD, PF_DEC}}},
[PPME_SOCKET_BIND_X] = {"bind",
EC_NET | EC_SYSCALL,
EF_USES_FD | EF_MODIFIES_STATE,
2,
{{"res", PT_ERRNO, PF_DEC}, {"addr", PT_SOCKADDR, PF_NA}}},
EF_USES_FD | EF_MODIFIES_STATE | EF_TMP_CONVERTER_MANAGED,
3,
{{"res", PT_ERRNO, PF_DEC},
{"addr", PT_SOCKADDR, PF_NA},
{"fd", PT_FD, PF_DEC}}},
[PPME_SOCKET_CONNECT_E] = {"connect",
EC_NET | EC_SYSCALL,
EF_USES_FD | EF_MODIFIES_STATE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ int BPF_PROG(bind_x, struct pt_regs *regs, long ret) {
uint16_t addrlen = (uint16_t)args[2];
auxmap__store_sockaddr_param(auxmap, sockaddr_ptr, addrlen);

/* Parameter 3: fd (type: PT_FD) */
auxmap__store_s64_param(auxmap, (int64_t)(int32_t)args[0]);

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

auxmap__finalize_event_header(auxmap);
Expand Down
14 changes: 8 additions & 6 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1630,16 +1630,13 @@ int f_sys_socket_bind_x(struct event_filler_arguments *args) {
unsigned long val;
struct sockaddr_storage address;
char *targetbuf = args->str_storage;
int32_t fd = 0;

/*
* res
*/
/* 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);

/*
* addr
*/
/* Parameter 2: addr (type: PT_SOCKADDR) */
syscall_get_arguments_deprecated(args, 1, 1, &val);

usrsockaddr = (struct sockaddr __user *)val;
Expand Down Expand Up @@ -1668,6 +1665,11 @@ int f_sys_socket_bind_x(struct event_filler_arguments *args) {
res = val_to_ring(args, (uint64_t)targetbuf, size, false, 0);
CHECK_RES(res);

/* Parameter 3: fd (type: PT_FD) */
fd = (int32_t)val;
res = val_to_ring(args, (int64_t)fd, 0, false, 0);
CHECK_RES(res);

return add_sentinel(args);
}

Expand Down
20 changes: 16 additions & 4 deletions test/drivers/test_suites/syscall_exit_suite/bind_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ TEST(SyscallExit, bindX_INET) {
/* Parameter 2: addr (type: PT_SOCKADDR) */
evt_test->assert_addr_info_inet_param(2, PPM_AF_INET, IPV4_SERVER, IPV4_PORT_SERVER_STRING);

/* Parameter 3: fd (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)server_socket_fd);

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

evt_test->assert_num_params_pushed(2);
evt_test->assert_num_params_pushed(3);
}

TEST(SyscallExit, bindX_INET6) {
Expand Down Expand Up @@ -101,9 +104,12 @@ TEST(SyscallExit, bindX_INET6) {
/* Parameter 2: addr (type: PT_SOCKADDR) */
evt_test->assert_addr_info_inet6_param(2, PPM_AF_INET6, IPV6_SERVER, IPV6_PORT_SERVER_STRING);

/* Parameter 3: fd (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)server_socket_fd);

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

evt_test->assert_num_params_pushed(2);
evt_test->assert_num_params_pushed(3);
}

#ifdef __NR_unlinkat
Expand Down Expand Up @@ -153,9 +159,12 @@ TEST(SyscallExit, bindX_UNIX) {
/* Parameter 2: addr (type: PT_SOCKADDR) */
evt_test->assert_addr_info_unix_param(2, PPM_AF_UNIX, UNIX_SERVER);

/* Parameter 3: fd (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)server_socket_fd);

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

evt_test->assert_num_params_pushed(2);
evt_test->assert_num_params_pushed(3);
}
#endif /* __NR_unlinkat */

Expand Down Expand Up @@ -195,9 +204,12 @@ TEST(SyscallExit, bindX_failure) {
/* Since the pointer to the `sockaddr` is `NULL` we expect an empty param here. */
evt_test->assert_empty_param(2);

/* Parameter 3: fd (type: PT_FD) */
evt_test->assert_numeric_param(3, (int64_t)mock_fd);

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

evt_test->assert_num_params_pushed(2);
evt_test->assert_num_params_pushed(3);
}

#endif
48 changes: 48 additions & 0 deletions test/libscap/test_suites/engines/savefile/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include "convert_event_test.h"
#include <sys/socket.h>
#include <netinet/in.h>

TEST_F(convert_event_test, conversion_not_needed) {
uint64_t ts = 12;
Expand Down Expand Up @@ -184,3 +186,49 @@ TEST_F(convert_event_test, PPME_SYSCALL_PREAD_X__to_4_params_with_enter) {
size,
pos));
}

////////////////////////////
// BIND
////////////////////////////

TEST_F(convert_event_test, PPME_SOCKET_BIND_E_store) {
uint64_t ts = 12;
int64_t tid = 25;

int64_t fd = 25;
uint32_t size = 89;

auto evt = create_safe_scap_event(ts, tid, PPME_SOCKET_BIND_E, 1, fd, size);
assert_single_conversion_skip(evt);
assert_event_storage_presence(evt);
}

TEST_F(convert_event_test, PPME_SOCKET_BIND_X_to_3_params_no_enter) {
uint64_t ts = 12;
int64_t tid = 25;

int64_t res = 89;
struct sockaddr_in sockaddr = {};
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(1234);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

// Defaulted to 0
int64_t fd = 0;

assert_single_conversion_success(
conversion_result::CONVERSION_COMPLETED,
create_safe_scap_event(ts,
tid,
PPME_SOCKET_BIND_X,
2,
res,
scap_const_sized_buffer{&sockaddr, sizeof(sockaddr)}),
create_safe_scap_event(ts,
tid,
PPME_SOCKET_BIND_X,
3,
res,
scap_const_sized_buffer{&sockaddr, sizeof(sockaddr)},
fd));
}
8 changes: 5 additions & 3 deletions userspace/libscap/engine/gvisor/fillers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,14 +1202,16 @@ int32_t fill_event_bind_x(scap_sized_buffer scap_buf,
size_t* event_size,
char* scap_err,
int64_t res,
scap_const_sized_buffer addr) {
scap_const_sized_buffer addr,
int64_t fd) {
return scap_event_encode_params(scap_buf,
event_size,
scap_err,
PPME_SOCKET_BIND_X,
2,
3,
res,
addr);
addr,
fd);
}

// PPME_SYSCALL_ACCEPT_5_E
Expand Down
3 changes: 2 additions & 1 deletion userspace/libscap/engine/gvisor/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ int32_t fill_event_bind_x(scap_sized_buffer scap_buf,
size_t* event_size,
char* scap_err,
int64_t res,
scap_const_sized_buffer addr);
scap_const_sized_buffer addr,
int64_t fd);

int32_t fill_event_accept_5_e(scap_sized_buffer scap_buf, size_t* event_size, char* scap_err);

Expand Down
3 changes: 2 additions & 1 deletion userspace/libscap/engine/gvisor/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,8 @@ static parse_result parse_bind(uint32_t id,
&ret.size,
scap_err,
gvisor_evt.exit().result(),
scap_const_sized_buffer{targetbuf, size});
scap_const_sized_buffer{targetbuf, size},
gvisor_evt.fd());
} else {
ret.status = scap_gvisor::fillers::fill_event_bind_e(scap_buf,
&ret.size,
Expand Down
3 changes: 3 additions & 0 deletions userspace/libscap/engine/savefile/converter/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ const std::unordered_map<conversion_key, conversion_info> g_conversion_table = {
.instrs({{C_INSTR_FROM_ENTER, 0},
{C_INSTR_FROM_ENTER, 1},
{C_INSTR_FROM_ENTER, 2}})},
{conversion_key{PPME_SOCKET_BIND_E, 1}, conversion_info().action(C_ACTION_STORE)},
{conversion_key{PPME_SOCKET_BIND_X, 2},
conversion_info().action(C_ACTION_ADD_PARAMS).instrs({{C_INSTR_FROM_ENTER, 0}})},
};
1 change: 1 addition & 0 deletions userspace/libscap/scap_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ int get_exit_event_fd_location(ppm_event_code etype) {
switch(etype) {
case PPME_SYSCALL_READ_X:
case PPME_SYSCALL_PREAD_X:
case PPME_SOCKET_BIND_X:
location = 2;
break;
default:
Expand Down
10 changes: 6 additions & 4 deletions userspace/libsinsp/test/events_net.ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,10 @@ TEST_F(sinsp_with_test_input, net_bind_listen_accept_ipv4) {
increasing_ts(),
1,
PPME_SOCKET_BIND_X,
2,
3,
return_value,
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()});
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()},
server_fd);
fdinfo = evt->get_fd_info();
ASSERT_NE(fdinfo, nullptr);
ASSERT_FALSE(fdinfo->is_ipv4_socket());
Expand Down Expand Up @@ -475,9 +476,10 @@ TEST_F(sinsp_with_test_input, net_bind_listen_accept_ipv6) {
increasing_ts(),
1,
PPME_SOCKET_BIND_X,
2,
3,
return_value,
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()});
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()},
server_fd);
std::string fdname =
std::string(DEFAULT_IPV6_SERVER_STRING) + ":" + std::string(DEFAULT_SERVER_PORT_STRING);
ASSERT_EQ(get_field_as_string(evt, "fd.name"), fdname);
Expand Down
9 changes: 7 additions & 2 deletions userspace/libsinsp/test/parsers/parse_connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,19 @@ TEST_F(sinsp_with_test_input, BIND_parse_unix_socket) {
sockaddr_un u_sockaddr = test_utils::fill_sockaddr_un(unix_path.c_str());
std::vector<uint8_t> server_sockaddr =
test_utils::pack_sockaddr(reinterpret_cast<sockaddr*>(&u_sockaddr));
uint64_t socket_fd = 77;
auto evt = add_event_advance_ts(
increasing_ts(),
INIT_TID,
PPME_SOCKET_BIND_X,
2,
3,
return_value,
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()});
scap_const_sized_buffer{server_sockaddr.data(), server_sockaddr.size()},
socket_fd);

// we want to check that `get_param_value_str` returns the correct unix socket path
ASSERT_EQ(evt->get_param_value_str("addr"), unix_path);

// we want to check that `get_fd_info()->m_fd` returns the correct socket fd.
ASSERT_EQ(evt->get_param_by_name("fd")->as<int64_t>(), socket_fd);
}

0 comments on commit eedda2e

Please sign in to comment.