From 38e20c8b8e3fcdfcf4b8ddefc7ba630a4bfe7726 Mon Sep 17 00:00:00 2001 From: Roberto Scolaro Date: Mon, 13 Jan 2025 22:01:23 +0000 Subject: [PATCH 1/5] feat(libsinsp_e2e): add unix_udp_client_server_read test Signed-off-by: Roberto Scolaro --- test/libsinsp_e2e/CMakeLists.txt | 1 + test/libsinsp_e2e/udp_client_server.cpp | 8 +- test/libsinsp_e2e/unix_client_server.cpp | 5 - test/libsinsp_e2e/unix_udp_client_server.cpp | 292 +++++++++++++++++++ 4 files changed, 296 insertions(+), 10 deletions(-) create mode 100644 test/libsinsp_e2e/unix_udp_client_server.cpp diff --git a/test/libsinsp_e2e/CMakeLists.txt b/test/libsinsp_e2e/CMakeLists.txt index 46dfb5d602..a0d71fe176 100755 --- a/test/libsinsp_e2e/CMakeLists.txt +++ b/test/libsinsp_e2e/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable( thread_state.cpp udp_client_server.cpp unix_client_server.cpp + unix_udp_client_server.cpp ) if(BUILD_BPF) diff --git a/test/libsinsp_e2e/udp_client_server.cpp b/test/libsinsp_e2e/udp_client_server.cpp index 439bee079b..dc1e4a9586 100644 --- a/test/libsinsp_e2e/udp_client_server.cpp +++ b/test/libsinsp_e2e/udp_client_server.cpp @@ -194,11 +194,9 @@ class udp_server { } void wait_for_server_ready() { - { - std::unique_lock lock(m_mutex); - m_condition_server_ready.wait(lock, [this]() { return m_server_ready; }); - m_server_ready = false; - } + std::unique_lock lock(m_mutex); + m_condition_server_ready.wait(lock, [this]() { return m_server_ready; }); + m_server_ready = false; } int64_t get_tid() { return m_tid; } diff --git a/test/libsinsp_e2e/unix_client_server.cpp b/test/libsinsp_e2e/unix_client_server.cpp index 0e9f0de51e..481ea62b48 100644 --- a/test/libsinsp_e2e/unix_client_server.cpp +++ b/test/libsinsp_e2e/unix_client_server.cpp @@ -38,17 +38,12 @@ limitations under the License. #include #include -#include -#include #include #define NAME "/tmp/python_unix_sockets_example" -#define PAYLOAD "0123456789QWERTYUIOPASDFGHJKLZXCVBNM" - #define PAYLOAD "0123456789QWERTYUIOPASDFGHJKLZXCVBNM" #define BUFFER_LENGTH (sizeof(PAYLOAD) - 1) -#define FALSE 0 inline void parse_tuple(const std::string& tuple, std::string& srcstr, diff --git a/test/libsinsp_e2e/unix_udp_client_server.cpp b/test/libsinsp_e2e/unix_udp_client_server.cpp new file mode 100644 index 0000000000..13a62b47d5 --- /dev/null +++ b/test/libsinsp_e2e/unix_udp_client_server.cpp @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 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. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include "event_capture.h" +#include "sys_call_test.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define NAME "/tmp/python_unix_udp_sockets_example" +#define PAYLOAD "0123456789QWERTYUIOPASDFGHJKLZXCVBNM" + +class unix_udp_server { +public: + unix_udp_server(bool use_recvfrom) { m_use_recvfrom = use_recvfrom; } + + void run() { + int sock; + struct sockaddr_un name; + struct sockaddr_un caddr; + socklen_t address_length = sizeof(struct sockaddr_un); + char buf[1024]; + + m_tid = syscall(SYS_gettid); + + /* Create socket from which to read. */ + sock = socket(AF_UNIX, SOCK_DGRAM, 0); + if(sock < 0) { + perror("opening datagram socket"); + exit(1); + } + + /* Create name. */ + name.sun_family = AF_UNIX; + strcpy(name.sun_path, NAME); + + if(::bind(sock, (struct sockaddr*)&name, SUN_LEN(&name))) { + perror("binding name to datagram socket"); + exit(1); + } + + { + std::unique_lock lock(m_mutex); + m_server_ready = true; + m_condition_server_ready.notify_one(); + } + + /* Read from the socket. */ + if(m_use_recvfrom) { + recvfrom(sock, buf, 1024, 0, (struct sockaddr*)&caddr, &address_length); + + recvfrom(sock, buf, 1024, 0, (struct sockaddr*)&caddr, &address_length); + } else { + ASSERT_TRUE(read(sock, buf, 1024) >= 0); + + ASSERT_TRUE(read(sock, buf, 1024) >= 0); + } + + close(sock); + + unlink(NAME); + } + + void wait_for_server_ready() { + std::unique_lock lock(m_mutex); + m_condition_server_ready.wait(lock, [this]() { return m_server_ready; }); + m_server_ready = false; + } + + int64_t get_tid() { return m_tid; } + +private: + std::mutex m_mutex; + std::condition_variable m_condition_server_ready; + bool m_server_ready = false; + int64_t m_tid; + bool m_use_recvfrom; +}; + +class unix_udp_client { +public: + void run() { + int sock; + struct sockaddr_un name; + + /* Create socket on which to send. */ + sock = socket(AF_UNIX, SOCK_DGRAM, 0); + if(sock < 0) { + perror("opening datagram socket"); + exit(1); + } + + /* Construct name of socket to send to. */ + name.sun_family = AF_UNIX; + strcpy(name.sun_path, NAME); + /* Send message. */ + + sendto(sock, + PAYLOAD, + sizeof(PAYLOAD) - 1, + 0, + (struct sockaddr*)&name, + sizeof(struct sockaddr_un)); + + sendto(sock, + PAYLOAD, + sizeof(PAYLOAD) - 1, + 0, + (struct sockaddr*)&name, + sizeof(struct sockaddr_un)); + + close(sock); + } +}; + +TEST_F(sys_call_test, unix_udp_client_server_read) { + int32_t callnum = 0; + std::string sport; + unix_udp_server server(false); + + // + // FILTER + // + event_filter_t filter = [&](sinsp_evt* evt) { + return evt->get_tid() == server.get_tid() || m_tid_filter(evt); + }; + + // + // INITIALIZATION + // + run_callback_t test = [&](sinsp* inspector) { + std::thread server_thread(&unix_udp_server::run, &server); + server.wait_for_server_ready(); + + unix_udp_client client; + client.run(); + + server_thread.join(); + }; + + // + // OUTPUT VALDATION + // + captured_event_callback_t callback = [&](const callback_param& param) { + sinsp_evt* evt = param.m_evt; + if(evt->get_type() == PPME_SOCKET_BIND_X) { + std::string ttuple = evt->get_param_value_str("addr"); + + EXPECT_EQ(NAME, ttuple); + + callnum++; + } + + if(evt->get_type() == PPME_SOCKET_SENDTO_E) { + std::string ttuple = evt->get_param_value_str("tuple"); + std::stringstream taddrs(ttuple.substr(0, ttuple.find(" "))); + std::string tfile = ttuple.substr(ttuple.find(" ") + 1); + + EXPECT_EQ(NAME, tfile); + + std::string token; + std::vector ttst; + while(std::getline(taddrs, token, '>')) { + ttst.push_back(token); + } + EXPECT_EQ(2, ttst.size()); + std::string tsrcstr = ttst[0].substr(0, ttst[0].size() - 1); + std::string tdststr = ttst[1]; + + if(evt->get_tid() == server.get_tid()) { + EXPECT_NE("0", tsrcstr); + EXPECT_EQ("0", tdststr); + } else { + EXPECT_EQ("0", tsrcstr); + EXPECT_NE("0", tdststr); + } + + std::string fdtuple = evt->get_param_value_str("fd"); + + if(fdtuple.length() > 3) { + std::string fdfile = fdtuple.substr(fdtuple.find(" ") + 1); + std::stringstream fdaddrs(fdtuple.substr(0, fdtuple.find(" "))); + + EXPECT_EQ(NAME, fdfile); + + std::vector fdtst; + while(std::getline(fdaddrs, token, '>')) { + fdtst.push_back(token); + } + EXPECT_EQ(3, fdtst.size()); + std::string fdsrcstr = fdtst[0].substr(0, fdtst[1].size() - 1); + std::string fddststr = fdtst[1]; + + EXPECT_EQ('u', fdtuple[1]); + + if(evt->get_tid() == server.get_tid()) { + EXPECT_NE("0", tsrcstr); + EXPECT_EQ("0", tdststr); + } else { + EXPECT_EQ("0", tsrcstr); + EXPECT_NE("0", tdststr); + } + } else { + if(fdtuple.length() == 1) { + EXPECT_EQ("u", fdtuple); + } + } + + if(evt->get_type() == PPME_SOCKET_SENDTO_X) { + EXPECT_EQ(PAYLOAD, evt->get_param_value_str("data")); + } + + callnum++; + } else if(evt->get_type() == PPME_SYSCALL_READ_E) { + if(callnum < 1) { + return; + } + + std::string fdtuple = evt->get_param_value_str("fd"); + + EXPECT_GT(fdtuple.length(), 1); + + if(fdtuple.length() > 1) { + std::string ttype = fdtuple.substr(0, fdtuple.find(">")); + std::string tfile = fdtuple.substr(fdtuple.find(">") + 1); + + if(ttype != "get_type() == PPME_SYSCALL_READ_X) { + if(PAYLOAD == evt->get_param_value_str("data")) { + callnum++; + } + } + }; + + ASSERT_NO_FATAL_FAILURE({ + event_capture::run(test, + callback, + filter, + event_capture::do_nothing, + event_capture::do_nothing, + event_capture::do_nothing, + libsinsp::events::all_sc_set()); + }); + EXPECT_EQ(7, callnum); +} From 780982020dc058a73efbf8a62cbdc01a7f8efe1e Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Tue, 14 Jan 2025 10:32:27 +0100 Subject: [PATCH 2/5] fix(driver): round of small fixes and improvements around unix socket paths handling in drivers. Signed-off-by: Federico Di Pierro --- driver/bpf/filler_helpers.h | 8 +++++--- .../helpers/store/auxmap_store_params.h | 18 +++++++----------- driver/ppm_events.c | 8 +++++++- test/libsinsp_e2e/unix_udp_client_server.cpp | 6 +++--- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index 56d9d57fda..1111ce4acc 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -428,6 +428,10 @@ static __always_inline bool bpf_getsockname(struct socket *sock, if(!addr) { sunaddr->sun_family = AF_UNIX; sunaddr->sun_path[0] = 0; + // The first byte to 0 can be confused with an `abstract socket address` for this reason + // we put also the second byte to 0 to comunicate to the caller that the address is not + // valid. + sunaddr->sun_path[1] = 0; } else { unsigned int len = _READ(addr->len); @@ -897,13 +901,11 @@ static __always_inline long bpf_fd_to_socktuple(struct filler_data *data, us_name = ((struct sockaddr_un *)peer_address)->sun_path; } - size = 1 + 8 + 8; int res = unix_socket_path( &data->buf[(data->state->tail_ctx.curoff + 1 + 8 + 8) & SCRATCH_SIZE_HALF], us_name, UNIX_PATH_MAX); - size += res; - + size = 1 + 8 + 8 + res; break; } } diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index c181012e3b..005fc4584a 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -776,7 +776,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * case AF_UNIX: { struct unix_sock *socket_local = (struct unix_sock *)sk; - struct unix_sock *socket_remote = (struct unix_sock *)BPF_CORE_READ(socket_local, peer); + struct unix_sock *socket_peer = (struct unix_sock *)BPF_CORE_READ(socket_local, peer); char *path = NULL; /* Pack the tuple info: @@ -787,18 +787,16 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * */ push__u8(auxmap->data, &auxmap->payload_pos, socket_family_to_scap(socket_family)); if(direction == OUTBOUND) { - push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_remote); + push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_peer); push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_local); - path = BPF_CORE_READ(socket_remote, addr, name[0].sun_path); + path = BPF_CORE_READ(socket_peer, addr, name[0].sun_path); // empty } else { push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_local); - push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_remote); + push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_peer); path = BPF_CORE_READ(socket_local, addr, name[0].sun_path); } - unsigned long start_reading_point; - char first_path_byte = *(char *)path; - if(first_path_byte == '\0') { + if(path[0] == '\0') { /* Please note exceptions in the `sun_path`: * Taken from: https://man7.org/linux/man-pages/man7/unix.7.html * @@ -808,14 +806,12 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * * * So in this case, we need to skip the initial `\0`. */ - start_reading_point = (unsigned long)path + 1; - } else { - start_reading_point = (unsigned long)path; + path++; } uint16_t written_bytes = push__charbuf(auxmap->data, &auxmap->payload_pos, - start_reading_point, + (unsigned long)path, MAX_UNIX_SOCKET_PATH, KERNEL); final_param_len = FAMILY_SIZE + KERNEL_POINTER + KERNEL_POINTER + written_bytes; diff --git a/driver/ppm_events.c b/driver/ppm_events.c index f1bc33af4a..731bd448bd 100644 --- a/driver/ppm_events.c +++ b/driver/ppm_events.c @@ -861,6 +861,11 @@ static struct socket *ppm_sockfd_lookup_light(int fd, int *err, int *fput_needed */ static void unix_socket_path(char *dest, const char *path, size_t size) { + if(path == NULL) { + dest[0] = '\0'; + return; + } + if(path[0] == '\0') { /* Please note exceptions in the `sun_path`: * Taken from: https://man7.org/linux/man-pages/man7/unix.7.html @@ -1173,7 +1178,8 @@ uint16_t fd_to_socktuple(int fd, } else { *(uint64_t *)(targetbuf + 1) = (uint64_t)(unsigned long)speer; *(uint64_t *)(targetbuf + 1 + 8) = (uint64_t)(unsigned long)us; - sock_getname(sock, (struct sockaddr *)&peer_address, 1); + err = sock_getname(sock, (struct sockaddr *)&peer_address, 1); + ASSERT(err == 0); us_name = ((struct sockaddr_un *)&peer_address)->sun_path; } diff --git a/test/libsinsp_e2e/unix_udp_client_server.cpp b/test/libsinsp_e2e/unix_udp_client_server.cpp index 13a62b47d5..b76a7f3d8d 100644 --- a/test/libsinsp_e2e/unix_udp_client_server.cpp +++ b/test/libsinsp_e2e/unix_udp_client_server.cpp @@ -57,8 +57,8 @@ class unix_udp_server { void run() { int sock; - struct sockaddr_un name; - struct sockaddr_un caddr; + struct sockaddr_un name = {}; + struct sockaddr_un caddr = {}; socklen_t address_length = sizeof(struct sockaddr_un); char buf[1024]; @@ -122,7 +122,7 @@ class unix_udp_client { public: void run() { int sock; - struct sockaddr_un name; + struct sockaddr_un name = {}; /* Create socket on which to send. */ sock = socket(AF_UNIX, SOCK_DGRAM, 0); From 258aa7e8f68b56db7697c3e9cf74bb07091c5653 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Tue, 14 Jan 2025 11:43:09 +0100 Subject: [PATCH 3/5] fix(driver): properly add back fallback to user data when peer socket data is missing. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- driver/bpf/filler_helpers.h | 5 +++++ driver/modern_bpf/helpers/store/auxmap_store_params.h | 10 +++++++++- driver/ppm_events.c | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index 1111ce4acc..86d10ad0e3 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -884,6 +884,7 @@ static __always_inline long bpf_fd_to_socktuple(struct filler_data *data, */ struct unix_sock *us = (struct unix_sock *)sk; struct sock *speer = _READ(us->peer); + struct sockaddr_un *usrsockaddr_un; char *us_name = NULL; data->buf[data->state->tail_ctx.curoff & SCRATCH_SIZE_HALF] = socket_family_to_scap(family); @@ -899,6 +900,10 @@ static __always_inline long bpf_fd_to_socktuple(struct filler_data *data, memcpy(&data->buf[(data->state->tail_ctx.curoff + 1 + 8) & SCRATCH_SIZE_HALF], &us, 8); bpf_getsockname(sock, peer_address, 1); us_name = ((struct sockaddr_un *)peer_address)->sun_path; + if(us_name[0] == '\0' && us_name[1] == '\0' && usrsockaddr != NULL) { + usrsockaddr_un = (struct sockaddr_un *)usrsockaddr; + us_name = usrsockaddr_un->sun_path; + } } int res = unix_socket_path( diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index 005fc4584a..fca2508c2d 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -777,6 +777,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * case AF_UNIX: { struct unix_sock *socket_local = (struct unix_sock *)sk; struct unix_sock *socket_peer = (struct unix_sock *)BPF_CORE_READ(socket_local, peer); + struct sockaddr_un usrsockaddr_un = {}; char *path = NULL; /* Pack the tuple info: @@ -789,7 +790,14 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * if(direction == OUTBOUND) { push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_peer); push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_local); - path = BPF_CORE_READ(socket_peer, addr, name[0].sun_path); // empty + if(socket_peer == NULL && usrsockaddr != NULL) { + bpf_probe_read_user(&usrsockaddr_un, + bpf_core_type_size(struct sockaddr_un), + (void *)usrsockaddr); + path = usrsockaddr_un.sun_path; + } else { + path = BPF_CORE_READ(socket_peer, addr, name[0].sun_path); + } } else { push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_local); push__u64(auxmap->data, &auxmap->payload_pos, (uint64_t)socket_peer); diff --git a/driver/ppm_events.c b/driver/ppm_events.c index 731bd448bd..a323c13f9b 100644 --- a/driver/ppm_events.c +++ b/driver/ppm_events.c @@ -1188,7 +1188,7 @@ uint16_t fd_to_socktuple(int fd, // Note that we check the second byte of `us_name`, see `sock_getname` for more details. // Some times `usrsockaddr` is provided as a NULL pointer, checking `use_userdata` should be // enough but just to be sure we check also `usrsockaddr != NULL` - if(us_name && us_name[1] == '\0' && use_userdata && usrsockaddr != NULL) { + if((!us_name || (us_name[0] == '\0' && us_name[1] == '\0')) && usrsockaddr != NULL) { usrsockaddr_un = (struct sockaddr_un *)usrsockaddr; /* From 6498f928582e01ad448a789b629e85648dfa1eae Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 14 Jan 2025 13:56:57 +0100 Subject: [PATCH 4/5] fix: always initialize `peer_address` in the kmod Signed-off-by: Andrea Terzolo --- driver/bpf/filler_helpers.h | 16 ++-- driver/ppm_events.c | 26 +++---- .../syscall_enter_suite/sendto_e.cpp | 76 +++++++++++++++++++ 3 files changed, 94 insertions(+), 24 deletions(-) diff --git a/driver/bpf/filler_helpers.h b/driver/bpf/filler_helpers.h index 86d10ad0e3..abb12e3231 100644 --- a/driver/bpf/filler_helpers.h +++ b/driver/bpf/filler_helpers.h @@ -425,14 +425,7 @@ static __always_inline bool bpf_getsockname(struct socket *sock, u = (struct unix_sock *)sk; addr = _READ(u->addr); - if(!addr) { - sunaddr->sun_family = AF_UNIX; - sunaddr->sun_path[0] = 0; - // The first byte to 0 can be confused with an `abstract socket address` for this reason - // we put also the second byte to 0 to comunicate to the caller that the address is not - // valid. - sunaddr->sun_path[1] = 0; - } else { + if(u && addr) { unsigned int len = _READ(addr->len); if(len > sizeof(struct sockaddr_storage)) @@ -444,6 +437,13 @@ static __always_inline bool bpf_getsockname(struct socket *sock, #else bpf_probe_read_kernel(sunaddr, len, addr->name); #endif + } else { + sunaddr->sun_family = AF_UNIX; + sunaddr->sun_path[0] = 0; + // The first byte to 0 can be confused with an `abstract socket address` for this reason + // we put also the second byte to 0 to comunicate to the caller that the address is not + // valid. + sunaddr->sun_path[1] = 0; } break; diff --git a/driver/ppm_events.c b/driver/ppm_events.c index a323c13f9b..23c7ecf1c6 100644 --- a/driver/ppm_events.c +++ b/driver/ppm_events.c @@ -233,30 +233,24 @@ inline int sock_getname(struct socket *sock, struct sockaddr *sock_address, int case AF_UNIX: { struct sockaddr_un *sunaddr = (struct sockaddr_un *)sock_address; struct unix_sock *u; - struct unix_address *u_addr = NULL; - if(peer) { + if(peer) sk = ((struct unix_sock *)sk)->peer; - if(!sk) { - return -ENOTCONN; - } - } u = (struct unix_sock *)sk; - u_addr = u->addr; - if(!u_addr) { + if(u && u->addr) { + unsigned int len = u->addr->len; + if(unlikely(len > sizeof(struct sockaddr_storage))) { + len = sizeof(struct sockaddr_storage); + } + memcpy(sunaddr, u->addr->name, len); + } else { sunaddr->sun_family = AF_UNIX; sunaddr->sun_path[0] = 0; // The first byte to 0 can be confused with an `abstract socket address` for this reason // we put also the second byte to 0 to comunicate to the caller that the address is not // valid. sunaddr->sun_path[1] = 0; - } else { - unsigned int len = u_addr->len; - if(unlikely(len > sizeof(struct sockaddr_storage))) { - len = sizeof(struct sockaddr_storage); - } - memcpy(sunaddr, u_addr->name, len); } break; } @@ -1004,8 +998,8 @@ uint16_t fd_to_socktuple(int fd, struct sockaddr_in *usrsockaddr_in; struct sockaddr_in6 *usrsockaddr_in6; uint16_t size; - struct sockaddr_storage sock_address; - struct sockaddr_storage peer_address; + struct sockaddr_storage sock_address = {}; + struct sockaddr_storage peer_address = {}; struct socket *sock; char *dest; struct unix_sock *us; diff --git a/test/drivers/test_suites/syscall_enter_suite/sendto_e.cpp b/test/drivers/test_suites/syscall_enter_suite/sendto_e.cpp index 97d1397f91..edb7d8513e 100644 --- a/test/drivers/test_suites/syscall_enter_suite/sendto_e.cpp +++ b/test/drivers/test_suites/syscall_enter_suite/sendto_e.cpp @@ -97,6 +97,82 @@ TEST(SyscallEnter, sendtoE_ipv4_tcp_NULL_sockaddr) { /*=============================== UDP ===========================*/ +TEST(SyscallEnter, sendtoE_unix_udp) { + auto evt_test = get_syscall_event_test(__NR_sendto, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + int32_t server_socket_fd = syscall(__NR_socket, AF_UNIX, SOCK_DGRAM, 0); + assert_syscall_state(SYSCALL_SUCCESS, "socket", server_socket_fd, NOT_EQUAL, -1); + evt_test->server_reuse_address_port(server_socket_fd); + sockaddr_un server_addr = {}; + evt_test->server_fill_sockaddr_un(&server_addr); + assert_syscall_state(SYSCALL_SUCCESS, + "bind (server)", + syscall(__NR_bind, server_socket_fd, &server_addr, sizeof(server_addr)), + NOT_EQUAL, + -1); + + int32_t client_socket_fd = syscall(__NR_socket, AF_UNIX, SOCK_DGRAM, 0); + assert_syscall_state(SYSCALL_SUCCESS, "socket", client_socket_fd, NOT_EQUAL, -1); + evt_test->client_reuse_address_port(client_socket_fd); + sockaddr_un client_addr = {}; + evt_test->client_fill_sockaddr_un(&client_addr); + assert_syscall_state(SYSCALL_SUCCESS, + "bind (client)", + syscall(__NR_bind, client_socket_fd, &client_addr, sizeof(client_addr)), + NOT_EQUAL, + -1); + + const void* sent_data = (const void*)SHORT_MESSAGE; + size_t sent_data_len = SHORT_MESSAGE_LEN; + uint32_t sendto_flags = 0; + + int64_t sent_bytes = syscall(__NR_sendto, + client_socket_fd, + sent_data, + sent_data_len, + sendto_flags, + &server_addr, + sizeof(server_addr)); + assert_syscall_state(SYSCALL_SUCCESS, "sendto (client)", sent_bytes, NOT_EQUAL, -1); + + syscall(__NR_shutdown, server_socket_fd, 2); + syscall(__NR_shutdown, client_socket_fd, 2); + close(client_socket_fd); + close(server_socket_fd); + syscall(__NR_unlinkat, 0, UNIX_CLIENT, 0); + syscall(__NR_unlinkat, 0, UNIX_SERVER, 0); + + /*=============================== 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 2: size (type: PT_UINT32)*/ + evt_test->assert_numeric_param(2, (uint32_t)SHORT_MESSAGE_LEN); + + /* Parameter 3: tuple (type: PT_SOCKTUPLE)*/ + evt_test->assert_tuple_unix_param(3, PPM_AF_UNIX, UNIX_SERVER); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(3); +} + TEST(SyscallEnter, sendtoE_ipv4_udp) { auto evt_test = get_syscall_event_test(__NR_sendto, ENTER_EVENT); From 600fefb36d2b0d70007bf6665103e06356d317af Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Tue, 14 Jan 2025 14:31:57 +0100 Subject: [PATCH 5/5] fix(driver/modern_bpf): lower sendmmsg and recvmmsg loop support to 8 to avoid limit size failures. Signed-off-by: Federico Di Pierro --- driver/modern_bpf/helpers/base/shared_size.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/modern_bpf/helpers/base/shared_size.h b/driver/modern_bpf/helpers/base/shared_size.h index ceeb369eae..7d81007ba7 100644 --- a/driver/modern_bpf/helpers/base/shared_size.h +++ b/driver/modern_bpf/helpers/base/shared_size.h @@ -27,7 +27,7 @@ #define MAX_IOVCNT 32 /* Maximum number of supported sendmmsg/recvmmsg messages */ -#define MAX_SENDMMSG_RECVMMSG_SIZE 16 +#define MAX_SENDMMSG_RECVMMSG_SIZE 8 /* Maximum number of `pollfd` structures that we can analyze. */ #define MAX_POLLFD 16