Skip to content

Commit

Permalink
new: support recv syscall
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
  • Loading branch information
Andreagit97 authored and poiana committed Mar 13, 2023
1 parent 94b7f87 commit 746a8af
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 0 deletions.
1 change: 1 addition & 0 deletions driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
#define GETRLIMIT_E_SIZE HEADER_LEN + sizeof(uint8_t) + PARAM_LEN
#define GETRLIMIT_X_SIZE HEADER_LEN + sizeof(int64_t) * 3 + PARAM_LEN * 3
#define SEND_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + PARAM_LEN * 2
#define RECV_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + PARAM_LEN * 2
#define NANOSLEEP_E_SIZE HEADER_LEN + sizeof(uint64_t) + PARAM_LEN
#define NANOSLEEP_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (C) 2023 The Falco Authors.
*
* This file is dual licensed under either the MIT or GPL 2. See MIT.txt
* or GPL2.txt for full copies of the license.
*/

#include <helpers/interfaces/variable_size_event.h>
#include <helpers/interfaces/fixed_size_event.h>

/*=============================== ENTER EVENT ===========================*/

SEC("tp_btf/sys_enter")
int BPF_PROG(recv_e,
struct pt_regs *regs,
long id)
{
struct ringbuf_struct ringbuf;
if(!ringbuf__reserve_space(&ringbuf, RECV_E_SIZE))
{
return 0;
}

ringbuf__store_event_header(&ringbuf, PPME_SOCKET_RECV_E);

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

/* Collect parameters at the beginning to manage socketcalls */
unsigned long args[3];
extract__network_args(args, 3, regs);

/* Parameter 1: fd (type: PT_FD) */
s32 fd = (s32)args[0];
ringbuf__store_s64(&ringbuf, (s64)fd);

/* Parameter 2: size (type: PT_UINT32) */
u32 size = (u32)args[2];
ringbuf__store_u32(&ringbuf, size);

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

ringbuf__submit_event(&ringbuf);

return 0;
}

/*=============================== ENTER EVENT ===========================*/

/*=============================== EXIT EVENT ===========================*/

SEC("tp_btf/sys_exit")
int BPF_PROG(recv_x,
struct pt_regs *regs,
long ret)
{
struct auxiliary_map *auxmap = auxmap__get();
if(!auxmap)
{
return 0;
}

auxmap__preload_event_header(auxmap, PPME_SOCKET_RECV_X);

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

/* Parameter 1: res (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

if(ret > 0)
{
/* Collect parameters at the beginning to manage socketcalls */
unsigned long args[2];
extract__network_args(args, 2, regs);

unsigned long bytes_to_read = maps__get_snaplen();
if(bytes_to_read > ret)
{
bytes_to_read = ret;
}

/* Parameter 2: data (type: PT_BYTEBUF) */
unsigned long data_pointer = args[1];
auxmap__store_bytebuf_param(auxmap, data_pointer, bytes_to_read, USER);
}
else
{
/* Parameter 2: data (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);
}

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

auxmap__finalize_event_header(auxmap);

auxmap__submit_event(auxmap);

return 0;
}

/*=============================== EXIT EVENT ===========================*/
46 changes: 46 additions & 0 deletions test/drivers/test_suites/syscall_enter_suite/recv_e.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "../../event_class/event_class.h"

#ifdef __NR_recv

TEST(SyscallEnter, recvE)
{
auto evt_test = get_syscall_event_test(__NR_recv, ENTER_EVENT);

evt_test->enable_capture();

/*=============================== TRIGGER SYSCALL ===========================*/

int32_t mock_fd = -1;
char* mock_buf = NULL;
size_t mock_count = DEFAULT_SNAPLEN;
int flags = 0;
assert_syscall_state(SYSCALL_FAILURE, "recv", syscall(__NR_recv, mock_fd, (void*)(mock_buf), mock_count, flags));

/*=============================== TRIGGER SYSCALL ===========================*/

evt_test->disable_capture();

evt_test->assert_event_presence();

if(HasFatalFailure())
{
return;
}

evt_test->parse_event();

evt_test->assert_header();

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

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

/* Parameter 2: size (type: PT_UINT32)*/
evt_test->assert_numeric_param(2, (uint32_t)mock_count);

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

evt_test->assert_num_params_pushed(2);
}
#endif
51 changes: 51 additions & 0 deletions test/drivers/test_suites/syscall_enter_suite/socketcall_e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,4 +940,55 @@ TEST(SyscallEnter, socketcall_sendE)
}
#endif

#ifdef __NR_recv

TEST(SyscallEnter, socketcall_recvE)
{
auto evt_test = get_syscall_event_test(__NR_recv, ENTER_EVENT);

evt_test->enable_capture();

/*=============================== TRIGGER SYSCALL ===========================*/

int32_t mock_fd = -1;
char *mock_buf = NULL;
size_t mock_count = DEFAULT_SNAPLEN;
int flags = 0;

unsigned long args[4] = {0};
args[0] = mock_fd;
args[1] = (unsigned long)mock_buf;
args[2] = mock_count;
args[3] = (unsigned long)flags;
assert_syscall_state(SYSCALL_FAILURE, "recv", syscall(__NR_socketcall, SYS_RECV, args));

/*=============================== TRIGGER SYSCALL ===========================*/

evt_test->disable_capture();

evt_test->assert_event_presence();

if(HasFatalFailure())
{
return;
}

evt_test->parse_event();

evt_test->assert_header();

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

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

/* Parameter 2: size (type: PT_UINT32)*/
evt_test->assert_numeric_param(2, (uint32_t)mock_count);

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

evt_test->assert_num_params_pushed(2);
}
#endif

#endif /* __NR_socketcall */
46 changes: 46 additions & 0 deletions test/drivers/test_suites/syscall_exit_suite/recv_x.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "../../event_class/event_class.h"

#ifdef __NR_recv
TEST(SyscallExit, recvX_fail)
{
auto evt_test = get_syscall_event_test(__NR_recv, EXIT_EVENT);

evt_test->enable_capture();

/*=============================== TRIGGER SYSCALL ===========================*/

int32_t mock_fd = -1;
char* mock_buf = NULL;
size_t mock_count = DEFAULT_SNAPLEN;
int flags = 0;
assert_syscall_state(SYSCALL_FAILURE, "recv", syscall(__NR_recv, mock_fd, (void*)(mock_buf), mock_count, flags));
int errno_value = -errno;

/*=============================== TRIGGER SYSCALL ===========================*/

evt_test->disable_capture();

evt_test->assert_event_presence();

if(HasFatalFailure())
{
return;
}

evt_test->parse_event();

evt_test->assert_header();

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

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

/* Parameter 2: data (type: PT_BYTEBUF) */
evt_test->assert_empty_param(2);

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

evt_test->assert_num_params_pushed(2);
}
#endif
51 changes: 51 additions & 0 deletions test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2952,4 +2952,55 @@ TEST(SyscallExit, socketcall_sendX)
}
#endif

#ifdef __NR_recv
TEST(SyscallExit, socketcall_recvX_fail)
{
auto evt_test = get_syscall_event_test(__NR_recv, EXIT_EVENT);

evt_test->enable_capture();

/*=============================== TRIGGER SYSCALL ===========================*/

int32_t mock_fd = -1;
char *mock_buf = NULL;
size_t mock_count = DEFAULT_SNAPLEN;
int flags = 0;

unsigned long args[4] = {0};
args[0] = mock_fd;
args[1] = (unsigned long)mock_buf;
args[2] = mock_count;
args[3] = (unsigned long)flags;
assert_syscall_state(SYSCALL_FAILURE, "recv", syscall(__NR_socketcall, SYS_RECV, args));
int errno_value = -errno;

/*=============================== TRIGGER SYSCALL ===========================*/

evt_test->disable_capture();

evt_test->assert_event_presence();

if(HasFatalFailure())
{
return;
}

evt_test->parse_event();

evt_test->assert_header();

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

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

/* Parameter 2: data (type: PT_BYTEBUF) */
evt_test->assert_empty_param(2);

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

evt_test->assert_num_params_pushed(2);
}
#endif

#endif /* __NR_socketcall */
2 changes: 2 additions & 0 deletions userspace/libpman/src/events_prog_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = {
[PPME_SYSCALL_GETRLIMIT_X] = "getrlimit_x",
[PPME_SOCKET_SEND_E] = "send_e",
[PPME_SOCKET_SEND_X] = "send_x",
[PPME_SOCKET_RECV_E] = "recv_e",
[PPME_SOCKET_RECV_X] = "recv_x",
[PPME_SYSCALL_NANOSLEEP_E] = "nanosleep_e",
[PPME_SYSCALL_NANOSLEEP_X] = "nanosleep_x",
[PPME_SYSCALL_UMOUNT_1_E] = "umount_e",
Expand Down

0 comments on commit 746a8af

Please sign in to comment.