diff --git a/.github/workflows/drivers_ci.yml b/.github/workflows/drivers_ci.yml index 09adf83f61..953d8312b1 100644 --- a/.github/workflows/drivers_ci.yml +++ b/.github/workflows/drivers_ci.yml @@ -181,7 +181,7 @@ jobs: runs-on: ubuntu-22.04 # Avoid running on forks since this job uses a private secret # not available on forks, leading to failures. - if: github.repository == 'falcosecurity/libs' + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == 'falcosecurity/libs' needs: paths-filter steps: - name: Extract branch name @@ -351,7 +351,7 @@ jobs: needs: paths-filter # Avoid running on forks since this job uses a private secret # not available on forks, leading to failures. - if: github.repository == 'falcosecurity/libs' && github.event_name == 'pull_request' && (needs.paths-filter.outputs.driver == 'true' || needs.paths-filter.outputs.libscap == 'true' || needs.paths-filter.outputs.libpman == 'true') + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'falcosecurity/libs' && (needs.paths-filter.outputs.driver == 'true' || needs.paths-filter.outputs.libscap == 'true' || needs.paths-filter.outputs.libpman == 'true') uses: ./.github/workflows/reusable_kernel_tests.yaml with: # Use real branch's HEAD sha, not the merge commit @@ -362,7 +362,7 @@ jobs: needs: kernel-tests-dev # Avoid running on forks since this job uses a private secret # not available on forks, leading to failures. - if: github.repository == 'falcosecurity/libs' && github.event_name == 'pull_request' && (needs.paths-filter.outputs.driver == 'true' || needs.paths-filter.outputs.libscap == 'true' || needs.paths-filter.outputs.libpman == 'true') + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'falcosecurity/libs' && (needs.paths-filter.outputs.driver == 'true' || needs.paths-filter.outputs.libscap == 'true' || needs.paths-filter.outputs.libpman == 'true') runs-on: ubuntu-latest steps: - name: Download X64 matrix diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 2fea026196..8432c3abd9 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -4,7 +4,7 @@ on: push: branches: - master - - 'release/**' + - "release/**" jobs: format: @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout repository 🎉 - uses: actions/checkout@v3 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: fetch-depth: 0 @@ -32,7 +32,7 @@ jobs: - name: Upload the git diff artifact 📦 if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: format_diff.patch path: ./format_diff.patch diff --git a/driver/configure/CLASS_CREATE_1/test.c b/driver/configure/CLASS_CREATE_1/test.c index fdf3344462..edee0ff5c7 100644 --- a/driver/configure/CLASS_CREATE_1/test.c +++ b/driver/configure/CLASS_CREATE_1/test.c @@ -21,6 +21,7 @@ MODULE_AUTHOR("the Falco authors"); static int class_create_test_init(void) { struct class *g_ppm_class = class_create("test"); + (void)g_ppm_class; return 0; } diff --git a/test/drivers/event_class/network_utils.h b/test/drivers/event_class/network_utils.h index 2c1d503a08..5550da5558 100644 --- a/test/drivers/event_class/network_utils.h +++ b/test/drivers/event_class/network_utils.h @@ -64,7 +64,7 @@ /*=============================== UNIX ===========================*/ /* Max length socket unix path. */ -#define MAX_SUN_PATH 109 +#define MAX_SUN_PATH 108 /* Unix Client: the `xyzxe-` prefix is used to avoid name collisions */ #define UNIX_CLIENT "/tmp/xyzxe-client" diff --git a/test/drivers/helpers/proc_parsing.h b/test/drivers/helpers/proc_parsing.h index 6c398cf375..ee4a85dfd5 100644 --- a/test/drivers/helpers/proc_parsing.h +++ b/test/drivers/helpers/proc_parsing.h @@ -12,18 +12,18 @@ * in which we don't need them all. */ struct proc_info { - uint32_t tty; - pid_t ppid; /* The PID of the parent of this process. */ - pid_t pgid; /* The process group ID of the process. */ - char raw_args[MAX_NUM_ARGS][MAX_PATH]; - const char* args[MAX_NUM_ARGS]; - uint32_t uid; - uint32_t gid; - uint32_t vpid; - uint32_t vtid; - struct rlimit file_rlimit; - uint32_t loginuid; - char exepath[MAX_PATH]; + uint32_t tty = 0; + pid_t ppid = 0; /* The PID of the parent of this process. */ + pid_t pgid = 0; /* The process group ID of the process. */ + char raw_args[MAX_NUM_ARGS][MAX_PATH] = {}; + const char* args[MAX_NUM_ARGS] = {}; + uint32_t uid = 0; + uint32_t gid = 0; + uint32_t vpid = 0; + uint32_t vtid = 0; + struct rlimit file_rlimit = {0, 0}; + uint32_t loginuid = 0; + char exepath[MAX_PATH] = {}; }; bool get_proc_info(pid_t pid, proc_info* info); diff --git a/test/drivers/test_suites/generic_tracepoints_suite/sched_process_exec.cpp b/test/drivers/test_suites/generic_tracepoints_suite/sched_process_exec.cpp index a050340333..8f86e50de7 100644 --- a/test/drivers/test_suites/generic_tracepoints_suite/sched_process_exec.cpp +++ b/test/drivers/test_suites/generic_tracepoints_suite/sched_process_exec.cpp @@ -42,7 +42,7 @@ TEST(GenericTracepoints, sched_proc_exec) { /* We need to use `SIGCHLD` otherwise the parent won't receive any signal * when the child terminates. */ - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args, sizeof(cl_args)); @@ -182,7 +182,7 @@ TEST(GenericTracepoints, sched_proc_exec_success_memfd) { /* We need to use `SIGCHLD` otherwise the parent won't receive any signal * when the child terminates. */ - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args, sizeof(cl_args)); diff --git a/test/drivers/test_suites/generic_tracepoints_suite/sched_process_fork.cpp b/test/drivers/test_suites/generic_tracepoints_suite/sched_process_fork.cpp index ceae169b82..f90f7fc0b6 100644 --- a/test/drivers/test_suites/generic_tracepoints_suite/sched_process_fork.cpp +++ b/test/drivers/test_suites/generic_tracepoints_suite/sched_process_fork.cpp @@ -14,7 +14,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3) { /*=============================== TRIGGER SYSCALL ===========================*/ /* Here we scan the parent just to obtain some info for the child */ - struct proc_info info = {0}; + struct proc_info info = {}; pid_t pid = ::getpid(); if(!get_proc_info(pid, &info)) { FAIL() << "Unable to get all the info from proc" << std::endl; @@ -23,7 +23,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3) { /* We need to use `SIGCHLD` otherwise the parent won't receive any signal * when the child terminates. We use `CLONE_FILES` just to test the flags. */ - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.flags = CLONE_FILES; cl_args.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args, sizeof(cl_args)); @@ -122,7 +122,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_create_child_with_2_threads pid_t p1_t1 = 61001; pid_t p1_t2 = 61004; - clone_args cl_args_parent = {0}; + clone_args cl_args_parent = {}; cl_args_parent.set_tid = (uint64_t)&p1_t1; cl_args_parent.set_tid_size = 1; cl_args_parent.exit_signal = SIGCHLD; @@ -131,7 +131,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_create_child_with_2_threads /* Create a child process that will spawn a new thread */ if(ret_pid == 0) { /* Spawn a new thread */ - clone_args cl_args_child = {0}; + clone_args cl_args_child = {}; cl_args_child.set_tid = (uint64_t)&p1_t2; cl_args_child.set_tid_size = 1; /* CLONE_PARENT has no additional effects if we are spawning a thread @@ -223,14 +223,14 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_child_clone_parent_flag) { pid_t p1_t1 = 61024; pid_t p2_t1 = 60128; - clone_args cl_args_parent = {0}; + clone_args cl_args_parent = {}; cl_args_parent.set_tid = (uint64_t)&p1_t1; cl_args_parent.set_tid_size = 1; cl_args_parent.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args_parent, sizeof(cl_args_parent)); if(ret_pid == 0) { - clone_args cl_args_child = {0}; + clone_args cl_args_child = {}; cl_args_child.set_tid = (uint64_t)&p2_t1; cl_args_child.set_tid_size = 1; cl_args_child.flags = CLONE_PARENT; @@ -327,7 +327,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_child_new_namespace_from_ch /* Here we create a child process in a new namespace. */ pid_t p1_t1[2] = {1, 61032}; - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.set_tid = (uint64_t)&p1_t1; cl_args.set_tid_size = 2; cl_args.flags = CLONE_NEWPID; @@ -411,7 +411,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_child_new_namespace_create_ /* Please note that a process can have the same pid number in different namespaces */ pid_t p1_t2[2] = {61036, 61036}; - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.set_tid = (uint64_t)&p1_t1; cl_args.set_tid_size = 2; cl_args.flags = CLONE_NEWPID; @@ -420,7 +420,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone3_child_new_namespace_create_ if(ret_pid == 0) { /* Spawn a new thread */ - clone_args cl_args_child = {0}; + clone_args cl_args_child = {}; cl_args_child.set_tid = (uint64_t)&p1_t2; cl_args_child.set_tid_size = 2; cl_args_child.flags = CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_VFORK; @@ -502,7 +502,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_clone) { /*=============================== TRIGGER SYSCALL ===========================*/ /* Here we scan the parent just to obtain some info for the child */ - struct proc_info info = {0}; + struct proc_info info = {}; pid_t pid = ::getpid(); if(!get_proc_info(pid, &info)) { FAIL() << "Unable to get all the info from proc" << std::endl; @@ -611,7 +611,7 @@ TEST(GenericTracepoints, sched_proc_fork_case_fork) { /*=============================== TRIGGER SYSCALL ===========================*/ /* Here we scan the parent just to obtain some info for the child */ - struct proc_info info = {0}; + struct proc_info info = {}; pid_t pid = ::getpid(); if(!get_proc_info(pid, &info)) { FAIL() << "Unable to get all the info from proc" << std::endl; diff --git a/test/drivers/test_suites/syscall_enter_suite/connect_e.cpp b/test/drivers/test_suites/syscall_enter_suite/connect_e.cpp index c5225e5313..fc6b6fed23 100644 --- a/test/drivers/test_suites/syscall_enter_suite/connect_e.cpp +++ b/test/drivers/test_suites/syscall_enter_suite/connect_e.cpp @@ -169,10 +169,10 @@ TEST(SyscallEnter, connectE_UNIX_failure) { */ #define UNIX_LONG_PATH \ "/unix_socket/test/too_long/too_long/too_long/too_long/unix_socket/test/too_long/too_long/" \ - "too_long/too_longgg*" + "too_long/too_longgg" #define EXPECTED_UNIX_LONG_PATH \ "/unix_socket/test/too_long/too_long/too_long/too_long/unix_socket/test/too_long/too_long/" \ - "too_long/too_longgg" + "too_long/too_longg" TEST(SyscallEnter, connectE_UNIX_max_path_failure) { auto evt_test = get_syscall_event_test(__NR_connect, ENTER_EVENT); diff --git a/test/drivers/test_suites/syscall_enter_suite/socketcall_e.cpp b/test/drivers/test_suites/syscall_enter_suite/socketcall_e.cpp index 7f2b05e9cb..5fe6b754d6 100644 --- a/test/drivers/test_suites/syscall_enter_suite/socketcall_e.cpp +++ b/test/drivers/test_suites/syscall_enter_suite/socketcall_e.cpp @@ -25,7 +25,7 @@ TEST(SyscallEnter, socketcall_socketE) { /* Here we need to call the `socket` from a child because the main process throws a `socket` * syscall to calibrate the socket file options if we are using the bpf probe. */ - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.flags = CLONE_FILES; cl_args.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args, sizeof(cl_args)); @@ -599,8 +599,8 @@ TEST(SyscallEnter, socketcall_sendtoE) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -679,8 +679,8 @@ TEST(SyscallEnter, socketcall_sendmsgE) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, diff --git a/test/drivers/test_suites/syscall_exit_suite/execveat_x.cpp b/test/drivers/test_suites/syscall_exit_suite/execveat_x.cpp index 3bf6285d5a..296a3ce65e 100644 --- a/test/drivers/test_suites/syscall_exit_suite/execveat_x.cpp +++ b/test/drivers/test_suites/syscall_exit_suite/execveat_x.cpp @@ -391,7 +391,6 @@ TEST(SyscallExit, execveatX_execve_exit) { /* Prepare the execve args */ int dirfd = 0; const char *pathname = "/usr/bin/echo"; - const char *comm = "echo"; const char *argv[] = {pathname, "[OUTPUT] SyscallExit.execveatX_success test", NULL}; const char *envp[] = {"IN_TEST=yes", "3_ARGUMENT=yes", "2_ARGUMENT=no", NULL}; int flags = 0; @@ -472,6 +471,7 @@ TEST(SyscallExit, execveatX_execve_exit) { evt_test->assert_empty_param(7); /* Parameter 14: comm (type: PT_CHARBUF) */ + const char *comm = "echo"; evt_test->assert_charbuf_param(14, comm); /* Parameter 15: cgroups (type: PT_CHARBUFARRAY) */ diff --git a/test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp b/test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp index 17e73c5089..f3364854a4 100644 --- a/test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp +++ b/test/drivers/test_suites/syscall_exit_suite/socketcall_x.cpp @@ -25,7 +25,7 @@ TEST(SyscallExit, socketcall_socketX) { /* Here we need to call the `socket` from a child because the main process throws a `socket` * syscall to calibrate the socket file options if we are using the bpf probe. */ - clone_args cl_args = {0}; + clone_args cl_args = {}; cl_args.flags = CLONE_FILES; cl_args.exit_signal = SIGCHLD; pid_t ret_pid = syscall(__NR_clone3, &cl_args, sizeof(cl_args)); @@ -370,8 +370,8 @@ TEST(SyscallExit, socketcall_acceptX_INET) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -458,8 +458,8 @@ TEST(SyscallExit, socketcall_acceptX_INET6) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in6 client_addr = {0}; - sockaddr_in6 server_addr = {0}; + sockaddr_in6 client_addr = {}; + sockaddr_in6 server_addr = {}; evt_test->connect_ipv6_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -547,8 +547,8 @@ TEST(SyscallExit, socketcall_acceptX_UNIX) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - struct sockaddr_un client_addr = {0}; - struct sockaddr_un server_addr = {0}; + struct sockaddr_un client_addr = {}; + struct sockaddr_un server_addr = {}; evt_test->connect_unix_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -693,8 +693,8 @@ TEST(SyscallExit, socketcall_accept4X_INET) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -774,8 +774,8 @@ TEST(SyscallExit, socketcall_accept4X_INET6) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in6 client_addr = {0}; - sockaddr_in6 server_addr = {0}; + sockaddr_in6 client_addr = {}; + sockaddr_in6 server_addr = {}; evt_test->connect_ipv6_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -856,8 +856,8 @@ TEST(SyscallExit, socketcall_accept4X_UNIX) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - struct sockaddr_un client_addr = {0}; - struct sockaddr_un server_addr = {0}; + struct sockaddr_un client_addr = {}; + struct sockaddr_un server_addr = {}; evt_test->connect_unix_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1040,8 +1040,8 @@ TEST(SyscallExit, socketcall_recvfromX_no_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1069,7 +1069,7 @@ TEST(SyscallExit, socketcall_recvfromX_no_snaplen) { /// TODO: if we use `sockaddr_in* src_addr = NULL` kernel module and old bpf are not able to get /// correct data. Fixing them means changing how we retrieve network data, so it would be quite /// a big change. - sockaddr_in src_addr = {0}; + sockaddr_in src_addr = {}; socklen_t addrlen = sizeof(src_addr); unsigned long args[6] = {0}; @@ -1137,8 +1137,8 @@ TEST(SyscallExit, socketcall_recvfromX_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1163,7 +1163,7 @@ TEST(SyscallExit, socketcall_recvfromX_snaplen) { char received_data[MAX_RECV_BUF_SIZE]; socklen_t received_data_len = MAX_RECV_BUF_SIZE; uint32_t recvfrom_flags = 0; - sockaddr_in src_addr = {0}; + sockaddr_in src_addr = {}; socklen_t addrlen = sizeof(src_addr); unsigned long args[6] = {0}; @@ -1424,8 +1424,8 @@ TEST(SyscallExit, socketcall_sendtoX_no_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1488,8 +1488,8 @@ TEST(SyscallExit, socketcall_sendtoX_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1664,8 +1664,8 @@ TEST(SyscallExit, socketcall_sendmsgX_no_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1738,8 +1738,8 @@ TEST(SyscallExit, socketcall_sendmsgX_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -1814,8 +1814,8 @@ TEST(SyscallExit, socketcall_sendmsgX_fail) { /*=============================== TRIGGER SYSCALL ===========================*/ int32_t mock_fd = -1; - struct msghdr send_msg = {0}; - struct iovec iov[1] = {0}; + struct msghdr send_msg = {}; + struct iovec iov[1] = {}; memset(&send_msg, 0, sizeof(send_msg)); memset(iov, 0, sizeof(iov)); char sent_data_1[DEFAULT_SNAPLEN / 2] = "some-data"; @@ -1867,7 +1867,7 @@ TEST(SyscallExit, socketcall_sendmsgX_null_iovec) { /*=============================== TRIGGER SYSCALL ===========================*/ int32_t mock_fd = -1; - struct msghdr send_msg = {0}; + struct msghdr send_msg = {}; memset(&send_msg, 0, sizeof(send_msg)); send_msg.msg_iov = NULL; /* here we pass a wrong `iovlen` to check the behavior */ @@ -1980,8 +1980,8 @@ TEST(SyscallExit, socketcall_recvmsgX_no_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -2098,8 +2098,8 @@ TEST(SyscallExit, socketcall_recvmsgX_snaplen) { int32_t client_socket_fd = 0; int32_t server_socket_fd = 0; - sockaddr_in client_addr = {0}; - sockaddr_in server_addr = {0}; + sockaddr_in client_addr = {}; + sockaddr_in server_addr = {}; evt_test->connect_ipv4_client_to_server(&client_socket_fd, &client_addr, &server_socket_fd, @@ -2369,7 +2369,7 @@ TEST(SyscallExit, socketcall_getsockoptX_SO_RCVTIMEO) { int32_t mock_fd = -1; int32_t level = SOL_SOCKET; int32_t option_name = SO_RCVTIMEO; - struct timeval option_value = {0}; + struct timeval option_value = {}; option_value.tv_sec = 5; option_value.tv_usec = 10; socklen_t option_len = sizeof(struct timeval); @@ -2822,7 +2822,7 @@ TEST(SyscallExit, socketcall_setsockoptX_SO_RCVTIMEO) { int32_t mock_fd = -1; int32_t level = SOL_SOCKET; int32_t option_name = SO_RCVTIMEO; - struct timeval option_value = {0}; + struct timeval option_value = {}; option_value.tv_sec = 5; option_value.tv_usec = 10; socklen_t option_len = sizeof(struct timeval); diff --git a/userspace/libpman/src/ringbuffer_definitions.h b/userspace/libpman/src/ringbuffer_definitions.h index 8c134b7a79..1f224926bc 100644 --- a/userspace/libpman/src/ringbuffer_definitions.h +++ b/userspace/libpman/src/ringbuffer_definitions.h @@ -20,6 +20,7 @@ limitations under the License. #include "state.h" #include +#include /* Taken from libbpf: /src/ringbuf.c */ struct ring { @@ -50,23 +51,3 @@ static inline int roundup_len(uint32_t len) { /* round up to 8 byte alignment */ return (len + 7) / 8 * 8; } - -/* Taken from libbpf: `include/linux/compiler.h` */ - -#define READ_ONCE(x) (*(volatile typeof(x) *)&x) -#define WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v) - -#define barrier() asm volatile("" ::: "memory") - -#define smp_store_release(p, v) \ - do { \ - barrier(); \ - WRITE_ONCE(*p, v); \ - } while(0) - -#define smp_load_acquire(p) \ - ({ \ - typeof(*p) ___p = READ_ONCE(*p); \ - barrier(); \ - ___p; \ - }) diff --git a/userspace/libscap/engine/bpf/scap_bpf.h b/userspace/libscap/engine/bpf/scap_bpf.h index 6c454646fc..a61dd3d5c2 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.h +++ b/userspace/libscap/engine/bpf/scap_bpf.h @@ -20,6 +20,7 @@ limitations under the License. #include #include +#include struct perf_event_sample { struct perf_event_header header; @@ -49,9 +50,7 @@ static inline void scap_bpf_get_buf_pointers(scap_device *dev, *phead = header->data_head; *ptail = header->data_tail; - // clang-format off - asm volatile("" ::: "memory"); - // clang-format on + mem_barrier(); uint64_t cons = *ptail % header->data_size; // consumer position uint64_t prod = *phead % header->data_size; // producer position @@ -154,9 +153,7 @@ static inline void scap_bpf_advance_tail(struct scap_device *dev) { header = (struct perf_event_mmap_page *)dev->m_buffer; - // clang-format off - asm volatile("" ::: "memory"); - // clang-format on + mem_barrier(); ASSERT(dev->m_lastreadsize > 0); /* `header->data_tail` is the consumer position. */ diff --git a/userspace/libscap/linux/barrier.h b/userspace/libscap/linux/barrier.h index 5cfc22f600..ed25c6a481 100644 --- a/userspace/libscap/linux/barrier.h +++ b/userspace/libscap/linux/barrier.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 /* -Copyright (C) 2023 The Falco Authors. +Copyright (C) 2024 The Falco Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,4 +17,61 @@ limitations under the License. */ #pragma once -#define mem_barrier() __sync_synchronize() +// This is taken from kernel headers `/include/linux/compiler.h` +// Used by libpman and scap_bpf engine + +#define READ_ONCE(x) (*(volatile typeof(x) *)&x) +#define WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v) + +#define barrier() asm volatile("" ::: "memory") + +#if defined(__x86_64__) + +#define smp_mb() asm volatile("lock; addl $0,-132(%%rsp)" ::: "memory", "cc") + +#define smp_store_release(p, v) \ + do { \ + barrier(); \ + WRITE_ONCE(*p, v); \ + } while(0) + +#define smp_load_acquire(p) \ + ({ \ + typeof(*p) ___p = READ_ONCE(*p); \ + barrier(); \ + ___p; \ + }) + +#elif defined(__aarch64__) + +#define smp_mb() asm volatile("dmb ish" ::: "memory") + +#endif + +#ifndef smp_mb +#define smp_mb() __sync_synchronize() +#endif + +#ifndef smp_store_release +#define smp_store_release(p, v) \ + do { \ + smp_mb(); \ + WRITE_ONCE(*p, v); \ + } while(0) +#endif + +#ifndef smp_load_acquire +#define smp_load_acquire(p) \ + ({ \ + typeof(*p) ___p = READ_ONCE(*p); \ + smp_mb(); \ + ___p; \ + }) +#endif + +// This is defined by us +#if defined(__x86_64__) +#define mem_barrier() barrier() +#else +#define mem_barrier() smp_mb() +#endif diff --git a/userspace/libsinsp/CMakeLists.txt b/userspace/libsinsp/CMakeLists.txt index f3abd43db1..be4ca47090 100644 --- a/userspace/libsinsp/CMakeLists.txt +++ b/userspace/libsinsp/CMakeLists.txt @@ -113,7 +113,7 @@ add_library( ) if(ENABLE_THREAD_POOL AND NOT EMSCRIPTEN) - target_sources(sinsp PRIVATE thread_pool_bs.cpp) + target_sources(sinsp PRIVATE sinsp_thread_pool_bs.cpp) endif() if(NOT WIN32 AND NOT APPLE) diff --git a/userspace/libsinsp/filter.cpp b/userspace/libsinsp/filter.cpp index 04d9b69d81..07abbed7a9 100644 --- a/userspace/libsinsp/filter.cpp +++ b/userspace/libsinsp/filter.cpp @@ -214,7 +214,6 @@ std::unique_ptr sinsp_filter_compiler::compile() { m_filter = std::make_unique(); m_last_boolop = BO_NONE; m_last_node_field = nullptr; - m_last_node_field_is_plugin = false; try { m_flt_ast->accept(this); } catch(const sinsp_exception& e) { @@ -278,7 +277,6 @@ static inline void check_op_type_compatibility(sinsp_filter_check& c) { void sinsp_filter_compiler::visit(const libsinsp::filter::ast::unary_check_expr* e) { m_pos = e->get_pos(); m_last_node_field = nullptr; - m_last_node_field_is_plugin = false; e->left->accept(this); if(!m_last_node_field) { throw sinsp_exception("filter error: missing field in left-hand of unary check"); @@ -320,13 +318,12 @@ static void add_filtercheck_value(sinsp_filter_check* chk, size_t idx, std::stri void sinsp_filter_compiler::visit(const libsinsp::filter::ast::binary_check_expr* e) { m_pos = e->get_pos(); m_last_node_field = nullptr; - m_last_node_field_is_plugin = false; e->left->accept(this); if(!m_last_node_field) { throw sinsp_exception("filter error: missing field in left-hand of binary check"); } - auto left_from_plugin = m_last_node_field_is_plugin; + auto left_ptr_unstable = m_last_node_field->get_field_info()->is_ptr_unstable(); auto check = std::move(m_last_node_field); // install cache on left-hand side extraction field @@ -335,13 +332,13 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::binary_check_expr check->m_cache_metrics = m_cache_factory->new_metrics(e->left.get(), node_info); check->m_extract_cache = m_cache_factory->new_extract_cache(e->left.get(), node_info); - // if the extraction comes from a plugin-implemented ield, then + // if the extraction comes from a plugin-implemented field, then // we need to add a storage transformer as the cache may end up storing a // shallow copy of the value pointers that are not valid anymore. Note that // this should not change the right field's eligibility for caching, as // the storage transformer does not alter the field's info. auto left_has_storage = false; - if(left_from_plugin && check->m_extract_cache) { + if(left_ptr_unstable && check->m_extract_cache) { left_has_storage = true; check->add_transformer(filter_transformer_type::FTR_STORAGE); } @@ -351,7 +348,6 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::binary_check_expr check_op_type_compatibility(*check); // Read the right-hand values of the filtercheck. - m_last_node_field_is_plugin = false; m_field_values.clear(); e->right->accept(this); @@ -379,8 +375,8 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::binary_check_expr // // However, we may have already added a storage modifier to the left field due to issues // with caching, in which case we are good already. - auto right_from_plugin = m_last_node_field_is_plugin; - if(!left_has_storage && left_from_plugin && right_from_plugin) { + auto right_ptr_unstable = m_last_node_field->get_field_info()->is_ptr_unstable(); + if(!left_has_storage && left_ptr_unstable && right_ptr_unstable) { check->add_transformer(filter_transformer_type::FTR_STORAGE); } @@ -404,7 +400,7 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::binary_check_expr // similarly as above, if the right-hand side extraction comes from a // plugin-implemented field, then we need to add an additional storage // layer on it as well - if(right_from_plugin && m_last_node_field->m_extract_cache) { + if(right_ptr_unstable && m_last_node_field->m_extract_cache) { m_last_node_field->add_transformer(filter_transformer_type::FTR_STORAGE); } @@ -554,8 +550,6 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::field_expr* e) { m_pos = e->get_pos(); auto field_name = create_filtercheck_name(e->field, e->arg); m_last_node_field = create_filtercheck(field_name); - m_last_node_field_is_plugin = - dynamic_cast(m_last_node_field.get()) != nullptr; if(m_last_node_field->parse_field_name(field_name, true, true) == -1) { throw sinsp_exception("filter error: can't parse field expression '" + field_name + "'"); } @@ -564,14 +558,13 @@ void sinsp_filter_compiler::visit(const libsinsp::filter::ast::field_expr* e) { void sinsp_filter_compiler::visit(const libsinsp::filter::ast::field_transformer_expr* e) { m_pos = e->get_pos(); m_last_node_field = nullptr; - m_last_node_field_is_plugin = false; e->value->accept(this); if(!m_last_node_field) { throw sinsp_exception("filter error: found null child node on '" + e->transformer + "' transformer"); } - // apply transformer, ignoring the "identity one" + // apply transformer, ignoring the "identity one" (it's just a syntactic construct) if(e->transformer != "val") { m_last_node_field->add_transformer(filter_transformer_from_str(e->transformer)); } diff --git a/userspace/libsinsp/filter.h b/userspace/libsinsp/filter.h index c5bc72cbc7..9a3661ea6e 100644 --- a/userspace/libsinsp/filter.h +++ b/userspace/libsinsp/filter.h @@ -270,7 +270,6 @@ class SINSP_PUBLIC sinsp_filter_compiler : private libsinsp::filter::ast::const_ libsinsp::filter::ast::pos_info m_pos; boolop m_last_boolop; std::unique_ptr m_last_node_field; - bool m_last_node_field_is_plugin; std::string m_flt_str; std::unique_ptr m_filter; std::vector m_field_values; diff --git a/userspace/libsinsp/filter_field.h b/userspace/libsinsp/filter_field.h index b46561d483..95abb635d1 100644 --- a/userspace/libsinsp/filter_field.h +++ b/userspace/libsinsp/filter_field.h @@ -46,6 +46,10 @@ enum filtercheck_field_flags { EPF_NO_TRANSFORMER = 1 << 11, ///< this field cannot have a field transformer. EPF_NO_RHS = 1 << 12, ///< this field cannot have a right-hand side filter check, and cannot be ///< used as a right-hand side filter check. + EPF_NO_PTR_STABILITY = + 1 << 13, ///< data pointers extracted by this field may change across subsequent + ///< extractions (even of other fields), which makes them unsafe to be used + ///< with filter caching or field-to-field comparisons }; /** @@ -93,6 +97,14 @@ struct filtercheck_field_info { // Returns true if this filter check can support an extraction transformer on it. // inline bool is_transformer_supported() const { return !(m_flags & EPF_NO_TRANSFORMER); } + + // + // Return true if this field extracts unstable data pointers that may change + // at subsequent extractions (even of other fields), thus not being safe to + // be used with caches or field-to-field filter comparisons, unless protected + // through a memory buffer copy (e.g. with a FTR_STORAGE transformer) + // + inline bool is_ptr_unstable() const { return m_flags & EPF_NO_PTR_STABILITY; } }; /** diff --git a/userspace/libsinsp/plugin.cpp b/userspace/libsinsp/plugin.cpp index d4e621cd86..88a04479a2 100644 --- a/userspace/libsinsp/plugin.cpp +++ b/userspace/libsinsp/plugin.cpp @@ -88,7 +88,7 @@ static void plugin_log_fn(ss_plugin_owner_t* o, std::shared_ptr sinsp_plugin::create( const plugin_api* api, const std::shared_ptr& treg, - const std::shared_ptr& tpool, + const std::shared_ptr& tpool, std::string& errstr) { char loadererr[PLUGIN_MAX_ERRLEN]; auto handle = plugin_load_api(api, loadererr); @@ -109,7 +109,7 @@ std::shared_ptr sinsp_plugin::create( std::shared_ptr sinsp_plugin::create( const std::string& filepath, const std::shared_ptr& treg, - const std::shared_ptr& tpool, + const std::shared_ptr& tpool, std::string& errstr) { char loadererr[PLUGIN_MAX_ERRLEN]; auto handle = plugin_load(filepath.c_str(), loadererr); @@ -463,7 +463,9 @@ bool sinsp_plugin::resolve_dylib_symbols(std::string& errstr) { m_fields.clear(); for(Json::Value::ArrayIndex j = 0; j < root.size(); j++) { filtercheck_field_info tf; - tf.m_flags = EPF_NONE; + + // plugin fields can't ever be trusted for pointer stability + tf.m_flags = EPF_NO_PTR_STABILITY; const Json::Value& jvtype = root[j]["type"]; string ftype = jvtype.asString(); @@ -740,11 +742,11 @@ std::vector sinsp_plugin::get_metrics() const { return metrics; } -thread_pool::routine_id_t sinsp_plugin::subscribe_routine( +sinsp_thread_pool::routine_id_t sinsp_plugin::subscribe_routine( ss_plugin_routine_fn_t routine_fn, ss_plugin_routine_state_t* routine_state) { if(!m_thread_pool) { - return reinterpret_cast(nullptr); + return reinterpret_cast(nullptr); } auto f = [this, routine_fn, routine_state]() -> bool { @@ -754,7 +756,7 @@ thread_pool::routine_id_t sinsp_plugin::subscribe_routine( return m_thread_pool->subscribe(f); } -bool sinsp_plugin::unsubscribe_routine(thread_pool::routine_id_t routine_id) { +bool sinsp_plugin::unsubscribe_routine(sinsp_thread_pool::routine_id_t routine_id) { if(!m_thread_pool || !routine_id) { return false; } @@ -773,7 +775,7 @@ ss_plugin_routine_t* plugin_subscribe_routine(ss_plugin_owner_t* o, ss_plugin_rc plugin_unsubscribe_routine(ss_plugin_owner_t* o, ss_plugin_routine_t* r) { auto t = static_cast(o); - auto id = reinterpret_cast(r); + auto id = reinterpret_cast(r); return t->unsubscribe_routine(id) ? SS_PLUGIN_SUCCESS : SS_PLUGIN_FAILURE; } diff --git a/userspace/libsinsp/plugin.h b/userspace/libsinsp/plugin.h index 0ab97de21f..155860e096 100644 --- a/userspace/libsinsp/plugin.h +++ b/userspace/libsinsp/plugin.h @@ -32,9 +32,9 @@ limitations under the License. #include #if defined(ENABLE_THREAD_POOL) && !defined(__EMSCRIPTEN__) -#include +#include #else -#include +#include #endif /** @@ -62,7 +62,7 @@ class sinsp_plugin { static std::shared_ptr create( const std::string& path, const std::shared_ptr& treg, - const std::shared_ptr& tpool, + const std::shared_ptr& tpool, std::string& errstr); /** @@ -72,7 +72,7 @@ class sinsp_plugin { static std::shared_ptr create( const plugin_api* api, const std::shared_ptr& treg, - const std::shared_ptr& tpool, + const std::shared_ptr& tpool, std::string& errstr); /** @@ -100,7 +100,7 @@ class sinsp_plugin { sinsp_plugin(plugin_handle_t* handle, const std::shared_ptr& treg, - const std::shared_ptr& tpool): + const std::shared_ptr& tpool): m_caps(CAP_NONE), m_name(), m_description(), @@ -158,9 +158,9 @@ class sinsp_plugin { std::vector get_metrics() const; bool capture_open(); bool capture_close(); - thread_pool::routine_id_t subscribe_routine(ss_plugin_routine_fn_t routine_fn, - ss_plugin_routine_state_t* routine_state); - bool unsubscribe_routine(thread_pool::routine_id_t routine_id); + sinsp_thread_pool::routine_id_t subscribe_routine(ss_plugin_routine_fn_t routine_fn, + ss_plugin_routine_state_t* routine_state); + bool unsubscribe_routine(sinsp_thread_pool::routine_id_t routine_id); /** Event Sourcing **/ inline uint32_t id() const { return m_id; } @@ -441,7 +441,7 @@ class sinsp_plugin { ss_plugin_state_type key_type); static ss_plugin_rc table_api_add_table(ss_plugin_owner_t* o, const ss_plugin_table_input* in); - std::shared_ptr m_thread_pool; + std::shared_ptr m_thread_pool; friend struct sinsp_table_wrapper; }; diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index d5636cc97d..760b68622d 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -136,7 +136,7 @@ sinsp::sinsp(bool with_metrics): m_table_registry->add_table(m_thread_manager.get()); #if defined(ENABLE_THREAD_POOL) && !defined(__EMSCRIPTEN__) - m_thread_pool = std::make_shared(); + m_thread_pool = std::make_shared(); #else m_thread_pool = nullptr; #endif @@ -1903,11 +1903,11 @@ void sinsp::set_track_connection_status(bool enabled) { m_parser->set_track_connection_status(enabled); } -std::shared_ptr sinsp::get_thread_pool() { +std::shared_ptr sinsp::get_thread_pool() { return m_thread_pool; } -bool sinsp::set_thread_pool(std::shared_ptr tpool) { +bool sinsp::set_thread_pool(std::shared_ptr tpool) { if(!m_thread_pool) { m_thread_pool = tpool; return true; diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 28f6edac70..28c16f40b1 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -927,8 +927,8 @@ class SINSP_PUBLIC sinsp : public capture_stats_source { bool get_track_connection_status() const; inline void set_track_connection_status(bool enabled); - std::shared_ptr get_thread_pool(); - bool set_thread_pool(std::shared_ptr tpool); + std::shared_ptr get_thread_pool(); + bool set_thread_pool(std::shared_ptr tpool); /** * \brief Get a new timestamp. @@ -1066,7 +1066,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source { int32_t m_quantization_interval = -1; - std::shared_ptr m_thread_pool; + std::shared_ptr m_thread_pool; public: std::unique_ptr m_thread_manager; diff --git a/userspace/libsinsp/sinsp_filtercheck.cpp b/userspace/libsinsp/sinsp_filtercheck.cpp index 55f831a4a4..f7a281f4db 100644 --- a/userspace/libsinsp/sinsp_filtercheck.cpp +++ b/userspace/libsinsp/sinsp_filtercheck.cpp @@ -688,7 +688,8 @@ void sinsp_filter_check::add_filter_value(std::unique_ptr rh } if(!rhs_chk->get_transformed_field_info()->is_rhs_field_supported()) { - throw sinsp_exception("field '" + std::string(get_transformed_field_info()->m_name) + + throw sinsp_exception("field '" + + std::string(rhs_chk->get_transformed_field_info()->m_name) + "' can't be used as a right-hand side field"); } diff --git a/userspace/libsinsp/sinsp_filtercheck_event.cpp b/userspace/libsinsp/sinsp_filtercheck_event.cpp index 5c4f0cd0a5..cb21635bbb 100644 --- a/userspace/libsinsp/sinsp_filtercheck_event.cpp +++ b/userspace/libsinsp/sinsp_filtercheck_event.cpp @@ -37,12 +37,6 @@ extern sinsp_evttables g_infotables; return (uint8_t*)&(x); \ } while(0) -#define RETURN_EXTRACT_PTR(x) \ - do { \ - *len = sizeof(*(x)); \ - return (uint8_t*)(x); \ - } while(0) - #define RETURN_EXTRACT_STRING(x) \ do { \ *len = (x).size(); \ @@ -162,7 +156,7 @@ const filtercheck_field_info sinsp_filter_check_event_fields[] = { "Arguments", "all the event arguments, aggregated into a single string."}, {PT_CHARBUF, - EPF_ARG_REQUIRED, + EPF_ARG_REQUIRED | EPF_NO_PTR_STABILITY, PF_NA, "evt.arg", "Argument", @@ -184,7 +178,7 @@ const filtercheck_field_info sinsp_filter_check_event_fields[] = { "(like writes to /dev/log) it provides higher level information coming from decoding the " "arguments."}, {PT_BYTEBUF, - EPF_NONE, + EPF_NO_PTR_STABILITY, PF_NA, "evt.buffer", "Buffer", @@ -198,7 +192,7 @@ const filtercheck_field_info sinsp_filter_check_event_fields[] = { "the length of the binary data buffer for events that have one, like read(), recvfrom(), " "etc."}, {PT_CHARBUF, - EPF_NONE, + EPF_NO_PTR_STABILITY, PF_DEC, "evt.res", "Return Value", diff --git a/userspace/libsinsp/thread_pool.h b/userspace/libsinsp/sinsp_thread_pool.h similarity index 93% rename from userspace/libsinsp/thread_pool.h rename to userspace/libsinsp/sinsp_thread_pool.h index bbfd2455fc..836ba67f1f 100644 --- a/userspace/libsinsp/thread_pool.h +++ b/userspace/libsinsp/sinsp_thread_pool.h @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#pragma once #include #include @@ -22,13 +23,13 @@ limitations under the License. #include #include -class thread_pool { +class sinsp_thread_pool { public: using routine_id_t = uintptr_t; - thread_pool() = default; + sinsp_thread_pool() = default; - virtual ~thread_pool() = default; + virtual ~sinsp_thread_pool() = default; /*! * \brief Subscribes a routine to the thread pool. diff --git a/userspace/libsinsp/thread_pool_bs.cpp b/userspace/libsinsp/sinsp_thread_pool_bs.cpp similarity index 70% rename from userspace/libsinsp/thread_pool_bs.cpp rename to userspace/libsinsp/sinsp_thread_pool_bs.cpp index a7ee88bb2f..40c295dac0 100644 --- a/userspace/libsinsp/thread_pool_bs.cpp +++ b/userspace/libsinsp/sinsp_thread_pool_bs.cpp @@ -16,15 +16,15 @@ limitations under the License. */ -#include +#include #include -void thread_pool_bs::default_bs_tp_deleter::operator()(BS::thread_pool* __ptr) const { +void sinsp_thread_pool_bs::default_bs_tp_deleter::operator()(BS::thread_pool* __ptr) const { std::default_delete{}(__ptr); } -thread_pool_bs::thread_pool_bs(size_t num_workers): m_pool(nullptr), m_routines() { +sinsp_thread_pool_bs::sinsp_thread_pool_bs(size_t num_workers): m_pool(nullptr), m_routines() { if(num_workers == 0) { m_pool = std::unique_ptr(new BS::thread_pool()); } else { @@ -33,15 +33,16 @@ thread_pool_bs::thread_pool_bs(size_t num_workers): m_pool(nullptr), m_routines( } } -thread_pool_bs::routine_id_t thread_pool_bs::subscribe(const std::function& func) { +sinsp_thread_pool_bs::routine_id_t sinsp_thread_pool_bs::subscribe( + const std::function& func) { m_routines.push_back(std::make_shared>(func)); auto& new_routine = m_routines.back(); run_routine(new_routine); - return reinterpret_cast(new_routine.get()); + return reinterpret_cast(new_routine.get()); } -bool thread_pool_bs::unsubscribe(thread_pool_bs::routine_id_t id) { +bool sinsp_thread_pool_bs::unsubscribe(sinsp_thread_pool_bs::routine_id_t id) { bool removed = false; m_routines.remove_if([id, &removed](const std::shared_ptr>& v) { if(v.get() == reinterpret_cast*>(id)) { @@ -55,18 +56,18 @@ bool thread_pool_bs::unsubscribe(thread_pool_bs::routine_id_t id) { return removed; } -void thread_pool_bs::purge() { +void sinsp_thread_pool_bs::purge() { m_routines.clear(); m_pool->purge(); m_pool->wait(); } -size_t thread_pool_bs::routines_num() { +size_t sinsp_thread_pool_bs::routines_num() { return m_routines.size(); } -void thread_pool_bs::run_routine(std::shared_ptr> routine) { +void sinsp_thread_pool_bs::run_routine(std::shared_ptr> routine) { m_pool->detach_task([this, routine] { if(routine.use_count() <= 1) { return; diff --git a/userspace/libsinsp/thread_pool_bs.h b/userspace/libsinsp/sinsp_thread_pool_bs.h similarity index 74% rename from userspace/libsinsp/thread_pool_bs.h rename to userspace/libsinsp/sinsp_thread_pool_bs.h index 065d0b5abf..2b0a20aab2 100644 --- a/userspace/libsinsp/thread_pool_bs.h +++ b/userspace/libsinsp/sinsp_thread_pool_bs.h @@ -15,22 +15,23 @@ See the License for the specific language governing permissions and limitations under the License. */ +#pragma once -#include +#include namespace BS { class thread_pool; }; -class thread_pool_bs : public thread_pool { +class sinsp_thread_pool_bs : public sinsp_thread_pool { public: - thread_pool_bs(size_t num_workers = 0); + sinsp_thread_pool_bs(size_t num_workers = 0); - virtual ~thread_pool_bs() { purge(); } + virtual ~sinsp_thread_pool_bs() { purge(); } - thread_pool::routine_id_t subscribe(const std::function& func); + sinsp_thread_pool::routine_id_t subscribe(const std::function& func); - bool unsubscribe(thread_pool::routine_id_t id); + bool unsubscribe(sinsp_thread_pool::routine_id_t id); void purge(); diff --git a/userspace/libsinsp/test/filter_compiler.ut.cpp b/userspace/libsinsp/test/filter_compiler.ut.cpp index 701fccbd1d..d5c55eaca0 100644 --- a/userspace/libsinsp/test/filter_compiler.ut.cpp +++ b/userspace/libsinsp/test/filter_compiler.ut.cpp @@ -827,6 +827,19 @@ TEST_F(sinsp_with_test_input, filter_cache_corner_cases) { cf->metrics->reset(); } +TEST_F(sinsp_with_test_input, filter_cache_pointer_instability) { + sinsp_filter_check_list flist; + + add_default_init_thread(); + open_inspector(); + + auto ff = std::make_shared(&m_inspector, flist); + auto cf = std::make_shared(); + auto evt = generate_proc_exit_event(2, INIT_TID); + + EXPECT_FALSE(eval_filter(evt, "(evt.arg.ret = val(evt.arg.reaper_tid))")); +} + TEST_F(sinsp_with_test_input, filter_regex_operator_evaluation) { // Basic case just to assert that the basic setup works add_default_init_thread(); diff --git a/userspace/libsinsp/test/sinsp_with_test_input.cpp b/userspace/libsinsp/test/sinsp_with_test_input.cpp index c5431994c3..25653e02cb 100644 --- a/userspace/libsinsp/test/sinsp_with_test_input.cpp +++ b/userspace/libsinsp/test/sinsp_with_test_input.cpp @@ -321,13 +321,14 @@ sinsp_evt* sinsp_with_test_input::generate_proc_exit_event(int64_t tid_to_remove // Scaffolding needed to call the PPME_PROCEXIT_1_E int64_t not_relevant_64 = 0; uint8_t not_relevant_8 = 0; + int64_t ret_err_perm = -1; // mostly non-relevant, used in few tests return add_event_advance_ts(increasing_ts(), tid_to_remove, PPME_PROCEXIT_1_E, 5, not_relevant_64, - not_relevant_64, + ret_err_perm, not_relevant_8, not_relevant_8, reaper_tid);