From 4522c0bdbb481633136023c099c900395c506ca1 Mon Sep 17 00:00:00 2001 From: notshivansh Date: Thu, 14 May 2026 19:55:40 +0530 Subject: [PATCH 1/7] fix for linux 4.18 --- ebpf/kernel/module.bpf.c | 153 ++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 82 deletions(-) diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 495b897a..ce574749 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -572,17 +572,6 @@ struct go_symaddrs_t { struct location_t ReadRet1Loc; }; -struct go_regabi_regs { - uint64_t regs[9]; -}; - -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(max_entries, 1); - __type(key, u32); - __type(value, struct go_regabi_regs); -} regs_heap SEC(".maps"); - struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1024); @@ -2008,38 +1997,36 @@ int probe_ret_SSL_read(struct pt_regs* ctx) { * Go TLS probes * =================================================================== */ -static __always_inline uint64_t* go_regabi_regs(const struct pt_regs* ctx) { - uint32_t kZero = 0; - struct go_regabi_regs* regs_heap_var = bpf_map_lookup_elem(®s_heap, &kZero); - if (regs_heap_var == NULL) { - return NULL; - } - +/* + * Snapshot Go register ABI args into caller stack memory only. + * Do not stash pt_regs fields in a map: the next bpf_map_lookup_elem() + * invalidates prior lookup pointers on older verifiers (e.g. RHEL 8 / 4.18), + * which would poison symaddrs/active_tls reads used with assign_arg(). + */ +static __always_inline void go_regabi_regs_fill(uint64_t regs_out[9], const struct pt_regs* ctx) { #if defined(TARGET_ARCH_X86_64) - regs_heap_var->regs[0] = ctx->ax; - regs_heap_var->regs[1] = ctx->bx; - regs_heap_var->regs[2] = ctx->cx; - regs_heap_var->regs[3] = ctx->di; - regs_heap_var->regs[4] = ctx->si; - regs_heap_var->regs[5] = ctx->r8; - regs_heap_var->regs[6] = ctx->r9; - regs_heap_var->regs[7] = ctx->r10; - regs_heap_var->regs[8] = ctx->r11; + regs_out[0] = ctx->ax; + regs_out[1] = ctx->bx; + regs_out[2] = ctx->cx; + regs_out[3] = ctx->di; + regs_out[4] = ctx->si; + regs_out[5] = ctx->r8; + regs_out[6] = ctx->r9; + regs_out[7] = ctx->r10; + regs_out[8] = ctx->r11; #elif defined(TARGET_ARCH_AARCH64) - regs_heap_var->regs[0] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[0]); - regs_heap_var->regs[1] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[1]); - regs_heap_var->regs[2] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[2]); - regs_heap_var->regs[3] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[3]); - regs_heap_var->regs[4] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[4]); - regs_heap_var->regs[5] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[5]); - regs_heap_var->regs[6] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[6]); - regs_heap_var->regs[7] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[7]); - regs_heap_var->regs[8] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[8]); + regs_out[0] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[0]); + regs_out[1] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[1]); + regs_out[2] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[2]); + regs_out[3] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[3]); + regs_out[4] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[4]); + regs_out[5] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[5]); + regs_out[6] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[6]); + regs_out[7] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[7]); + regs_out[8] = BPF_CORE_READ((const struct user_pt_regs *)(const void *)ctx, regs[8]); #else #error Target Architecture not supported #endif - - return regs_heap_var->regs; } static inline uint64_t get_goid(struct pt_regs* ctx) { @@ -2148,16 +2135,16 @@ int probe_entry_tls_conn_write(struct pt_regs* ctx) { tgid_goid.tgid, tgid_goid.goid); } - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { + struct go_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); + if (symaddrs_p == NULL) { return 0; } + struct go_symaddrs_t symaddrs = *symaddrs_p; - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + const void* sp = (const void*)PT_REGS_SP(ctx); + uint64_t regs_buf[9] = {}; + go_regabi_regs_fill(regs_buf, ctx); + uint64_t* regs = regs_buf; if (print_bpf_logs) { bpf_printk("probe_entry_tls_conn_write 2 %lu %llu", @@ -2166,9 +2153,9 @@ int probe_entry_tls_conn_write(struct pt_regs* ctx) { struct go_tls_conn_args args = {}; assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), - symaddrs->WriteConnectionLoc, sp, regs); + symaddrs.WriteConnectionLoc, sp, regs); assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), - symaddrs->WriteBufferLoc, sp, regs); + symaddrs.WriteBufferLoc, sp, regs); bpf_map_update_elem(&active_tls_conn_op_map, &tgid_goid, &args, BPF_ANY); @@ -2182,22 +2169,22 @@ int probe_entry_tls_conn_write(struct pt_regs* ctx) { static __always_inline int probe_return_tls_conn_write_core(struct pt_regs* ctx, uint64_t id, uint32_t tgid, struct go_tls_conn_args* args) { - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { + struct go_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); + if (symaddrs_p == NULL) { return 0; } + struct go_symaddrs_t symaddrs = *symaddrs_p; - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + const void* sp = (const void*)PT_REGS_SP(ctx); + uint64_t regs_buf[9] = {}; + go_regabi_regs_fill(regs_buf, ctx); + uint64_t* regs = regs_buf; int64_t retval0 = 0; - assign_arg(&retval0, sizeof(retval0), symaddrs->WriteRet0Loc, sp, regs); + assign_arg(&retval0, sizeof(retval0), symaddrs.WriteRet0Loc, sp, regs); struct go_interface retval1 = {}; - assign_arg(&retval1, sizeof(retval1), symaddrs->WriteRet1Loc, sp, regs); + assign_arg(&retval1, sizeof(retval1), symaddrs.WriteRet1Loc, sp, regs); if (print_bpf_logs) { bpf_printk("probe_return_tls_conn_write 2.1 %llu %lu", id, tgid); @@ -2210,7 +2197,7 @@ static __always_inline int probe_return_tls_conn_write_core(struct pt_regs* ctx, struct go_interface conn_intf; conn_intf.type = 1; conn_intf.ptr = args->conn_ptr; - int fd = get_fd_from_conn_intf_core(conn_intf, symaddrs); + int fd = get_fd_from_conn_intf_core(conn_intf, &symaddrs); u32 fdu = (u32)fd; if (print_bpf_logs) { @@ -2258,17 +2245,18 @@ int probe_return_tls_conn_write(struct pt_regs* ctx) { tgid_goid.tgid, tgid_goid.goid); } - struct go_tls_conn_args* args = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); - if (args == NULL) { + struct go_tls_conn_args* args_ptr = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); + if (args_ptr == NULL) { return 0; } + struct go_tls_conn_args args_local = *args_ptr; if (print_bpf_logs) { bpf_printk("probe_return_tls_conn_write 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); } - probe_return_tls_conn_write_core(ctx, id, tgid, args); + probe_return_tls_conn_write_core(ctx, id, tgid, &args_local); bpf_map_delete_elem(&active_tls_conn_op_map, &tgid_goid); @@ -2297,16 +2285,16 @@ int probe_entry_tls_conn_read(struct pt_regs* ctx) { tgid_goid.tgid, tgid_goid.goid); } - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { + struct go_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); + if (symaddrs_p == NULL) { return 0; } + struct go_symaddrs_t symaddrs = *symaddrs_p; - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + const void* sp = (const void*)PT_REGS_SP(ctx); + uint64_t regs_buf[9] = {}; + go_regabi_regs_fill(regs_buf, ctx); + uint64_t* regs = regs_buf; if (print_bpf_logs) { bpf_printk("probe_entry_tls_conn_read 2 %lu %llu", @@ -2315,9 +2303,9 @@ int probe_entry_tls_conn_read(struct pt_regs* ctx) { struct go_tls_conn_args args = {}; assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), - symaddrs->ReadConnectionLoc, sp, regs); + symaddrs.ReadConnectionLoc, sp, regs); assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), - symaddrs->ReadBufferLoc, sp, regs); + symaddrs.ReadBufferLoc, sp, regs); bpf_map_update_elem(&active_tls_conn_op_map, &tgid_goid, &args, BPF_ANY); @@ -2332,22 +2320,22 @@ int probe_entry_tls_conn_read(struct pt_regs* ctx) { static __always_inline int probe_return_tls_conn_read_core(struct pt_regs* ctx, uint64_t id, uint32_t tgid, struct go_tls_conn_args* args) { - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { + struct go_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); + if (symaddrs_p == NULL) { return 0; } + struct go_symaddrs_t symaddrs = *symaddrs_p; - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + const void* sp = (const void*)PT_REGS_SP(ctx); + uint64_t regs_buf[9] = {}; + go_regabi_regs_fill(regs_buf, ctx); + uint64_t* regs = regs_buf; int64_t retval0 = 0; - assign_arg(&retval0, sizeof(retval0), symaddrs->ReadRet0Loc, sp, regs); + assign_arg(&retval0, sizeof(retval0), symaddrs.ReadRet0Loc, sp, regs); struct go_interface retval1 = {}; - assign_arg(&retval1, sizeof(retval1), symaddrs->ReadRet1Loc, sp, regs); + assign_arg(&retval1, sizeof(retval1), symaddrs.ReadRet1Loc, sp, regs); if (print_bpf_logs) { bpf_printk("probe_return_tls_conn_read 2.1 %llu %lu", id, tgid); @@ -2360,7 +2348,7 @@ static __always_inline int probe_return_tls_conn_read_core(struct pt_regs* ctx, struct go_interface conn_intf; conn_intf.type = 1; conn_intf.ptr = args->conn_ptr; - int fd = get_fd_from_conn_intf_core(conn_intf, symaddrs); + int fd = get_fd_from_conn_intf_core(conn_intf, &symaddrs); u32 fdu = (u32)fd; if (print_bpf_logs) { @@ -2408,17 +2396,18 @@ int probe_return_tls_conn_read(struct pt_regs* ctx) { tgid_goid.tgid, tgid_goid.goid); } - struct go_tls_conn_args* args = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); - if (args == NULL) { + struct go_tls_conn_args* args_ptr = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); + if (args_ptr == NULL) { return 0; } + struct go_tls_conn_args args_local = *args_ptr; if (print_bpf_logs) { bpf_printk("probe_return_tls_conn_read 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); } - probe_return_tls_conn_read_core(ctx, id, tgid, args); + probe_return_tls_conn_read_core(ctx, id, tgid, &args_local); bpf_map_delete_elem(&active_tls_conn_op_map, &tgid_goid); From 8ef003c35fe4b069abbf43a2add12e124bd0d0ed Mon Sep 17 00:00:00 2001 From: notshivansh Date: Thu, 14 May 2026 20:09:41 +0530 Subject: [PATCH 2/7] fix ? --- ebpf/kernel/module.bpf.c | 258 +++++++++++++++++++++++---------------- 1 file changed, 150 insertions(+), 108 deletions(-) diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index ce574749..4ac39b20 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -617,8 +617,13 @@ static __always_inline u64 gen_tgid_fd(u32 tgid, int fd) { } static __always_inline void process_syscall_accept(struct pt_regs* ctx, - const struct accept_args_t* args, + const struct accept_args_t* args_in, u64 id, bool isConnect) { + if (args_in == NULL) { + return; + } + struct accept_args_t args = *args_in; + int ret_fd = PT_REGS_RC(ctx); if (!isConnect && ret_fd < 0) { @@ -631,13 +636,13 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, u32 srcIp = 0; uint16_t lport = 0; - if (args->addr != NULL) { + if (args.addr != NULL) { if (print_bpf_logs) { bpf_printk("sock addr found, processing"); } } - if (args->sock_alloc_socket != NULL) { + if (args.sock_alloc_socket != NULL) { if (print_bpf_logs) { bpf_printk("sock alloc found, processing"); } @@ -652,7 +657,7 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, */ struct akto_socket sock_hdr = {}; if (bpf_probe_read_kernel(&sock_hdr, sizeof(sock_hdr), - args->sock_alloc_socket) != 0) + args.sock_alloc_socket) != 0) return; struct sock* sk = (struct sock *)(unsigned long)sock_hdr.sk; @@ -696,9 +701,9 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, } if (!socketConn) { - if (args->addr != NULL) { + if (args.addr != NULL) { struct akto_sockaddr sa_hdr = {}; - if (bpf_probe_read_user(&sa_hdr, sizeof(sa_hdr), args->addr) != 0) { + if (bpf_probe_read_user(&sa_hdr, sizeof(sa_hdr), args.addr) != 0) { return; } if (sa_hdr.sa_family != AF_INET && sa_hdr.sa_family != AF_INET6) { @@ -711,24 +716,24 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, conn_info.id = id; if (isConnect) { - conn_info.fd = args->fd; + conn_info.fd = args.fd; } else { conn_info.fd = ret_fd; } conn_info.conn_start_ns = bpf_ktime_get_ns(); - if (!socketConn && args->addr != NULL) { + if (!socketConn && args.addr != NULL) { struct akto_sockaddr sa_hdr = {}; - bpf_probe_read_user(&sa_hdr, sizeof(sa_hdr), args->addr); + bpf_probe_read_user(&sa_hdr, sizeof(sa_hdr), args.addr); if (sa_hdr.sa_family == AF_INET) { struct akto_sockaddr_in sin = {}; - if (bpf_probe_read_user(&sin, sizeof(sin), args->addr) == 0) { + if (bpf_probe_read_user(&sin, sizeof(sin), args.addr) == 0) { conn_info.port = sin.sin_port; conn_info.ip = sin.sin_addr; } } else { struct akto_sockaddr_in6 sin6 = {}; - if (bpf_probe_read_user(&sin6, sizeof(sin6), args->addr) == 0) { + if (bpf_probe_read_user(&sin6, sizeof(sin6), args.addr) == 0) { conn_info.port = sin6.sin6_port; conn_info.ip = ((__u32 *)sin6.sin6_addr)[3]; } @@ -741,7 +746,7 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, if (filter_local_traffic && conn_info.ip == local_traffic_ip) { if (print_bpf_logs) { - bpf_printk("Dropping local traffic ip:%u fd:%d", conn_info.ip, args->fd); + bpf_printk("Dropping local traffic ip:%u fd:%d", conn_info.ip, args.fd); } return; } @@ -749,7 +754,7 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, u32 tgid = id >> 32; u64 tgid_fd = 0; if (isConnect) { - tgid_fd = gen_tgid_fd(tgid, args->fd); + tgid_fd = gen_tgid_fd(tgid, args.fd); } else { tgid_fd = gen_tgid_fd(tgid, ret_fd); } @@ -759,15 +764,16 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, int val = 0; u32 val_key = 0; if (counter != NULL) { - if ((*counter) > (TRAFFIC_MAX_CONNECTION_MAP_SIZE - 5)) { - int reset = 0; - bpf_map_update_elem(&conn_counter, &idx, &reset, BPF_ANY); + int c = *counter; + if (c > (TRAFFIC_MAX_CONNECTION_MAP_SIZE - 5)) { if (print_bpf_logs) { - bpf_printk("conn_info_counter reset: %d", *counter); + bpf_printk("conn_info_counter reset: %d", c); } + c = 0; } - (*counter)++; - val = *counter; + c++; + bpf_map_update_elem(&conn_counter, &idx, &c, BPF_ANY); + val = c; val_key = (u32)val; if (print_bpf_logs) { bpf_printk("conn_info_counter found: %d", val); @@ -822,24 +828,30 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, } static __always_inline void process_syscall_close(struct pt_regs* ctx, - const struct close_args_t* args, + const struct close_args_t* args_in, u64 id) { + if (args_in == NULL) { + return; + } + struct close_args_t args = *args_in; + int ret_val = PT_REGS_RC(ctx); if (ret_val < 0) { return; } - if (args->fd < 0) { + if (args.fd < 0) { return; } u32 tgid = id >> 32; - u64 tgid_fd = gen_tgid_fd(tgid, args->fd); - struct conn_info_t* conn_info = bpf_map_lookup_elem(&conn_info_map, &tgid_fd); - if (conn_info == NULL) { + u64 tgid_fd = gen_tgid_fd(tgid, args.fd); + struct conn_info_t* conn_info_p = bpf_map_lookup_elem(&conn_info_map, &tgid_fd); + if (conn_info_p == NULL) { return; } + struct conn_info_t conn_info = *conn_info_p; if (!disable_ring_submit) { increment_counter(&socket_close_submit_total); @@ -848,11 +860,11 @@ static __always_inline void process_syscall_close(struct pt_regs* ctx, if (socket_close_event == NULL) { increment_counter(&socket_close_submit_failed_total); } else { - socket_close_event->id = conn_info->id; - socket_close_event->fd = conn_info->fd; - socket_close_event->conn_start_ns = conn_info->conn_start_ns; - socket_close_event->port = conn_info->port; - socket_close_event->ip = conn_info->ip; + socket_close_event->id = conn_info.id; + socket_close_event->fd = conn_info.fd; + socket_close_event->conn_start_ns = conn_info.conn_start_ns; + socket_close_event->port = conn_info.port; + socket_close_event->ip = conn_info.ip; socket_close_event->socket_close_ns = bpf_ktime_get_ns(); bpf_ringbuf_submit(socket_close_event, 0); } @@ -883,12 +895,17 @@ static __noinline u32 bounded_probe_read_user( } static __noinline void process_syscall_data(struct pt_regs* ctx, - const struct data_args_t* args, + const struct data_args_t* args_in, u64 id, bool is_send, bool ssl) { + if (args_in == NULL) { + return; + } + struct data_args_t args = *args_in; + int bytes_exchanged = PT_REGS_RC(ctx); - if (args->iovlen > 0 && args->buf_size > 0) { - bytes_exchanged = args->buf_size; + if (args.iovlen > 0 && args.buf_size > 0) { + bytes_exchanged = args.buf_size; } if (bytes_exchanged <= 0) { @@ -898,28 +915,30 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, if (print_bpf_logs) { bpf_printk("SSL data 1 %d", id); } - if (args->fd < 0) { + if (args.fd < 0) { return; } u32 tgid = id >> 32; - u64 tgid_fd = gen_tgid_fd(tgid, args->fd); + u64 tgid_fd = gen_tgid_fd(tgid, args.fd); if (print_bpf_logs) { bpf_printk("SSL data 2 %d %llu %lu", id, tgid_fd, tgid); } - struct conn_info_t* conn_info = bpf_map_lookup_elem(&conn_info_map, &tgid_fd); - if (conn_info == NULL) { + struct conn_info_t* conn_info_p = bpf_map_lookup_elem(&conn_info_map, &tgid_fd); + if (conn_info_p == NULL) { return; } + struct conn_info_t conn_info = *conn_info_p; + if (print_bpf_logs) { bpf_printk("SSL data 3 %d %llu %lu", id, tgid_fd, tgid); } - if (conn_info->ssl != ssl) { + if (conn_info.ssl != ssl) { return; } - if (filter_strict_remote_port && conn_info->port != strict_remote_port) { + if (filter_strict_remote_port && conn_info.port != strict_remote_port) { return; } @@ -935,20 +954,6 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, bpf_printk("SSL data 4 %llu %llu %d", id, tgid_fd, ssl); } - u32 kZero = 0; - struct socket_data_event_t* socket_data_event = - bpf_map_lookup_elem(&socket_data_event_buffer_heap, &kZero); - if (socket_data_event == NULL) { - return; - } - - socket_data_event->id = conn_info->id; - socket_data_event->fd = conn_info->fd; - socket_data_event->conn_start_ns = conn_info->conn_start_ns; - socket_data_event->port = conn_info->port; - socket_data_event->ip = conn_info->ip; - socket_data_event->ssl = conn_info->ssl; - int bytes_sent = 0; u32 size_to_save = 0; int i = 0; @@ -959,6 +964,21 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, if (bytes_remaining <= 0) { break; } + + u32 kZero = 0; + struct socket_data_event_t* socket_data_event = + bpf_map_lookup_elem(&socket_data_event_buffer_heap, &kZero); + if (socket_data_event == NULL) { + break; + } + + socket_data_event->id = conn_info.id; + socket_data_event->fd = conn_info.fd; + socket_data_event->conn_start_ns = conn_info.conn_start_ns; + socket_data_event->port = conn_info.port; + socket_data_event->ip = conn_info.ip; + socket_data_event->ssl = conn_info.ssl; + u32 current_size; if (bytes_remaining > MAX_MSG_SIZE && (i != CHUNK_LIMIT - 1)) { current_size = (u32)MAX_MSG_SIZE; @@ -968,24 +988,24 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, u32 read_size = bounded_probe_read_user( socket_data_event, current_size, - (const char *)args->buf + bytes_sent); + (const char *)args.buf + bytes_sent); if (read_size == 0 && current_size > 0) { break; } size_to_save = read_size; if (is_send) { - conn_info->writeEventsCount = (conn_info->writeEventsCount) + 1u; + conn_info.writeEventsCount = conn_info.writeEventsCount + 1u; } else { - conn_info->readEventsCount = (conn_info->readEventsCount) + 1u; + conn_info.readEventsCount = conn_info.readEventsCount + 1u; } - socket_data_event->writeEventsCount = conn_info->writeEventsCount; - socket_data_event->readEventsCount = conn_info->readEventsCount; + socket_data_event->writeEventsCount = conn_info.writeEventsCount; + socket_data_event->readEventsCount = conn_info.readEventsCount; if (print_bpf_logs) { bpf_printk("pid: %d conn-id:%d, fd: %d", - id, conn_info->id, conn_info->fd); + id, conn_info.id, conn_info.fd); bpf_printk("current_size: %d i:%d, bytes_exchanged: %d", current_size, i, bytes_exchanged); bpf_printk("rwc: %d tdfd: %llu data: %s", @@ -1007,15 +1027,22 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, bytes_sent += current_size; } + + bpf_map_update_elem(&conn_info_map, &tgid_fd, &conn_info, BPF_ANY); } static __noinline void process_syscall_data_vecs(struct pt_regs* ctx, - struct data_args_t* args, + struct data_args_t* args_in, u64 id, bool is_send) { + if (args_in == NULL) { + return; + } + struct data_args_t args = *args_in; + int bytes_sent = 0; int total_size = PT_REGS_RC(ctx); - const struct iovec* iov = args->iov; - for (int i = 0; i < LOOP_LIMIT && i < args->iovlen && bytes_sent < total_size; ++i) { + const struct iovec* iov = args.iov; + for (int i = 0; i < LOOP_LIMIT && i < args.iovlen && bytes_sent < total_size; ++i) { struct iovec iov_cpy; bpf_probe_read_user(&iov_cpy, sizeof(iov_cpy), &iov[i]); @@ -1023,9 +1050,9 @@ static __noinline void process_syscall_data_vecs(struct pt_regs* ctx, const size_t iov_size = iov_cpy.iov_len < bytes_remaining ? iov_cpy.iov_len : bytes_remaining; - args->buf = iov_cpy.iov_base; - args->buf_size = iov_size; - process_syscall_data(ctx, args, id, is_send, false); + args.buf = iov_cpy.iov_base; + args.buf_size = iov_size; + process_syscall_data(ctx, &args, id, is_send, false); bytes_sent += iov_size; } } @@ -1062,10 +1089,11 @@ int syscall__probe_ret_accept(struct pt_regs* ctx) { bpf_printk("syscall__probe_ret_accept: pid: %d", id); } - struct accept_args_t* accept_args = bpf_map_lookup_elem(&active_accept_args_map, &id); + struct accept_args_t* accept_args_p = bpf_map_lookup_elem(&active_accept_args_map, &id); - if (accept_args != NULL) { - process_syscall_accept(ctx, accept_args, id, false); + if (accept_args_p != NULL) { + struct accept_args_t accept_args = *accept_args_p; + process_syscall_accept(ctx, &accept_args, id, false); } bpf_map_delete_elem(&active_accept_args_map, &id); @@ -1080,13 +1108,15 @@ int probe_ret_sock_alloc(struct pt_regs* ctx) { bpf_printk("probe_ret_sock_alloc: pid: %d", id); } - struct accept_args_t* accept_args = bpf_map_lookup_elem(&active_accept_args_map, &id); - if (accept_args == NULL) { + struct accept_args_t* accept_args_p = bpf_map_lookup_elem(&active_accept_args_map, &id); + if (accept_args_p == NULL) { return 0; } + struct accept_args_t accept_args = *accept_args_p; - if (accept_args->sock_alloc_socket == NULL) { - accept_args->sock_alloc_socket = (struct socket*)PT_REGS_RC(ctx); + if (accept_args.sock_alloc_socket == NULL) { + accept_args.sock_alloc_socket = (struct socket*)PT_REGS_RC(ctx); + bpf_map_update_elem(&active_accept_args_map, &id, &accept_args, BPF_ANY); } return 0; @@ -1100,13 +1130,15 @@ int probe_entry_tcp_connect(struct pt_regs* ctx) { bpf_printk("probe_entry_tcp_connect: pid: %d", id); } - struct accept_args_t* accept_args = bpf_map_lookup_elem(&active_accept_args_map, &id); - if (accept_args == NULL) { + struct accept_args_t* accept_args_p = bpf_map_lookup_elem(&active_accept_args_map, &id); + if (accept_args_p == NULL) { return 0; } + struct accept_args_t accept_args = *accept_args_p; - if (accept_args->sock == NULL) { - accept_args->sock = (void*)PT_REGS_PARM1(ctx); + if (accept_args.sock == NULL) { + accept_args.sock = (void*)PT_REGS_PARM1(ctx); + bpf_map_update_elem(&active_accept_args_map, &id, &accept_args, BPF_ANY); } return 0; @@ -1139,14 +1171,15 @@ int syscall__probe_ret_connect(struct pt_regs* ctx) { bpf_printk("syscall__probe_ret_connect: pid: %d", id); } - struct accept_args_t* accept_args = bpf_map_lookup_elem(&active_accept_args_map, &id); + struct accept_args_t* accept_args_p = bpf_map_lookup_elem(&active_accept_args_map, &id); - if (accept_args != NULL) { - if (accept_args->sock != NULL) { - struct sock* sock = accept_args->sock; - accept_args->sock_alloc_socket = BPF_CORE_READ(sock, sk_socket); + if (accept_args_p != NULL) { + struct accept_args_t accept_args = *accept_args_p; + if (accept_args.sock != NULL) { + struct sock* sock = accept_args.sock; + accept_args.sock_alloc_socket = BPF_CORE_READ(sock, sk_socket); } - process_syscall_accept(ctx, accept_args, id, true); + process_syscall_accept(ctx, &accept_args, id, true); } bpf_map_delete_elem(&active_accept_args_map, &id); @@ -1742,10 +1775,10 @@ static void set_conn_as_ssl(u32 tgid, u32 fd) { if (conn_info == NULL) { return; } + conn_info->ssl = true; if (print_bpf_logs) { bpf_printk("SSL marking ssl tgid: %d", tgid_fd); } - conn_info->ssl = true; } /* @@ -1811,26 +1844,27 @@ int BPF_UPROBE(probe_entry_SSL_write, void* ssl, void* buf, int num) { __u64* tls_wrap_val = bpf_map_lookup_elem(&node_ssl_tls_wrap_map, &ssl_key); u32 fd = 0; if (tls_wrap_val != NULL) { - /* get_fd_node logic inlined for the node case */ + __u64 tls_wrap_word = *tls_wrap_val; u32 tgid_key = tgid; - struct node_tlswrap_symaddrs_t* symaddrs = + struct node_tlswrap_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&node_tlswrap_symaddrs_map, &tgid_key); - if (symaddrs != NULL) { - void* tls_wrap = (void*)*tls_wrap_val; - void* stream_ptr = tls_wrap + symaddrs->TLSWrapStreamListenerOffset - + symaddrs->StreamListenerStreamOffset; + if (symaddrs_p != NULL) { + struct node_tlswrap_symaddrs_t symaddrs = *symaddrs_p; + void* tls_wrap = (void*)tls_wrap_word; + void* stream_ptr = tls_wrap + symaddrs.TLSWrapStreamListenerOffset + + symaddrs.StreamListenerStreamOffset; void* stream = NULL; bpf_probe_read(&stream, sizeof(stream), stream_ptr); if (stream != NULL) { void* uv_stream_ptr = stream - - symaddrs->StreamBaseStreamResourceOffset - - symaddrs->LibuvStreamWrapStreamBaseOffset - + symaddrs->LibuvStreamWrapStreamOffset; + - symaddrs.StreamBaseStreamResourceOffset + - symaddrs.LibuvStreamWrapStreamBaseOffset + + symaddrs.LibuvStreamWrapStreamOffset; void* uv_stream = NULL; bpf_probe_read(&uv_stream, sizeof(uv_stream), uv_stream_ptr); if (uv_stream != NULL) { - int32_t* fd_ptr = uv_stream + symaddrs->UVStreamSIOWatcherOffset - + symaddrs->UVIOSFDOffset; + int32_t* fd_ptr = uv_stream + symaddrs.UVStreamSIOWatcherOffset + + symaddrs.UVIOSFDOffset; int32_t fd_val = 0; if (bpf_probe_read(&fd_val, sizeof(fd_val), fd_ptr) == 0) { fd = (u32)fd_val; @@ -1932,25 +1966,27 @@ int BPF_UPROBE(probe_entry_SSL_read, void* ssl, void* buf, int num) { __u64* tls_wrap_val = bpf_map_lookup_elem(&node_ssl_tls_wrap_map, &ssl_key); int32_t fd = 0; if (tls_wrap_val != NULL) { + __u64 tls_wrap_word = *tls_wrap_val; u32 tgid_key = tgid; - struct node_tlswrap_symaddrs_t* symaddrs = + struct node_tlswrap_symaddrs_t* symaddrs_p = bpf_map_lookup_elem(&node_tlswrap_symaddrs_map, &tgid_key); - if (symaddrs != NULL) { - void* tls_wrap = (void*)*tls_wrap_val; - void* stream_ptr = tls_wrap + symaddrs->TLSWrapStreamListenerOffset - + symaddrs->StreamListenerStreamOffset; + if (symaddrs_p != NULL) { + struct node_tlswrap_symaddrs_t symaddrs = *symaddrs_p; + void* tls_wrap = (void*)tls_wrap_word; + void* stream_ptr = tls_wrap + symaddrs.TLSWrapStreamListenerOffset + + symaddrs.StreamListenerStreamOffset; void* stream = NULL; bpf_probe_read(&stream, sizeof(stream), stream_ptr); if (stream != NULL) { void* uv_stream_ptr = stream - - symaddrs->StreamBaseStreamResourceOffset - - symaddrs->LibuvStreamWrapStreamBaseOffset - + symaddrs->LibuvStreamWrapStreamOffset; + - symaddrs.StreamBaseStreamResourceOffset + - symaddrs.LibuvStreamWrapStreamBaseOffset + + symaddrs.LibuvStreamWrapStreamOffset; void* uv_stream = NULL; bpf_probe_read(&uv_stream, sizeof(uv_stream), uv_stream_ptr); if (uv_stream != NULL) { - int32_t* fd_ptr = uv_stream + symaddrs->UVStreamSIOWatcherOffset - + symaddrs->UVIOSFDOffset; + int32_t* fd_ptr = uv_stream + symaddrs.UVStreamSIOWatcherOffset + + symaddrs.UVIOSFDOffset; int32_t fd_val = 0; if (bpf_probe_read(&fd_val, sizeof(fd_val), fd_ptr) == 0) { fd = fd_val; @@ -2002,6 +2038,10 @@ int probe_ret_SSL_read(struct pt_regs* ctx) { * Do not stash pt_regs fields in a map: the next bpf_map_lookup_elem() * invalidates prior lookup pointers on older verifiers (e.g. RHEL 8 / 4.18), * which would poison symaddrs/active_tls reads used with assign_arg(). + * + * Same rule elsewhere: copy `*map_ptr` to the stack (or re-lookup) before any + * other bpf helper if you still need the map value; never use two live map-value + * pointers across helpers; refresh per-CPU scratch after ringbuf_output / stats. */ static __always_inline void go_regabi_regs_fill(uint64_t regs_out[9], const struct pt_regs* ctx) { #if defined(TARGET_ARCH_X86_64) @@ -2032,10 +2072,11 @@ static __always_inline void go_regabi_regs_fill(uint64_t regs_out[9], const stru static inline uint64_t get_goid(struct pt_regs* ctx) { uint64_t id = bpf_get_current_pid_tgid(); uint32_t tgid = id >> 32; - struct go_symaddrs_t* common_symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (common_symaddrs == NULL) { + struct go_symaddrs_t* common_symaddrs_p = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); + if (common_symaddrs_p == NULL) { return 0; } + struct go_symaddrs_t common_symaddrs = *common_symaddrs_p; /* CO-RE: resolve task_struct->thread field offsets from BTF. */ struct task_struct* task_ptr = (struct task_struct*)bpf_get_current_task(); @@ -2068,7 +2109,7 @@ static inline uint64_t get_goid(struct pt_regs* ctx) { size_t g_addr; bpf_probe_read_user(&g_addr, sizeof(void*), (void*)(fs_base + g_addr_offset)); bpf_probe_read_user(&goid, sizeof(void*), - (void*)(g_addr + common_symaddrs->GIDOffset)); + (void*)(g_addr + common_symaddrs.GIDOffset)); return goid; } @@ -2213,7 +2254,8 @@ static __always_inline int probe_return_tls_conn_write_core(struct pt_regs* ctx, bpf_printk("probe_return_tls_conn_write 2.2 %llu %lu", id, tgid); } - struct data_args_t data_args; + /* Full zero-init: process_syscall_data reads iovlen/buf_size; stack garbage fails strict verifiers. */ + struct data_args_t data_args = {}; data_args.source_fn = kGoTLSWrite; data_args.buf = args->plaintext_ptr; data_args.fd = fd; @@ -2364,7 +2406,7 @@ static __always_inline int probe_return_tls_conn_read_core(struct pt_regs* ctx, bpf_printk("probe_return_tls_conn_read 2.2 %llu %lu", id, tgid); } - struct data_args_t data_args; + struct data_args_t data_args = {}; data_args.source_fn = kGoTLSRead; data_args.buf = args->plaintext_ptr; data_args.fd = fd; From 29c8592c7a7de2fff3b0ea0616a688e122bae613 Mon Sep 17 00:00:00 2001 From: notshivansh Date: Thu, 14 May 2026 20:42:40 +0530 Subject: [PATCH 3/7] fix ? --- ebpf/kernel/module.bpf.c | 56 +++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 4ac39b20..04f40a0d 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -596,19 +596,51 @@ static __always_inline bool is_system_cpu_ingest_paused(void) { return paused != NULL && *paused != 0; } -static __noinline long output_to_data_shard( - void *data, u64 size) { +/* + * Ringbuf submit size for struct socket_data_event_t: header + valid bytes in msg[]. + * Keep bounds explicit for strict verifiers (RHEL 8 / 4.18): bpf_ringbuf_output R3 + * must not depend on un-clamped arithmetic from syscall return values. + */ +static __always_inline u32 socket_data_event_output_len(u32 msg_len) { + const u32 hdr_sz = (u32)(sizeof(struct socket_data_event_t) - MAX_MSG_SIZE); + u32 pl = msg_len; + if (pl > MAX_MSG_SIZE) { + pl = MAX_MSG_SIZE; + } + u32 out = hdr_sz + pl; + const u32 cap = (u32)sizeof(struct socket_data_event_t); + if (out > cap) { + out = cap; + } + return out; +} + +static __noinline long output_to_data_shard(void *data, u64 size) { + /* + * bpf_ringbuf_output size (R3) must be provably bounded on older verifiers + * (e.g. RHEL 8 / 4.18): "R3 unbounded memory access, use 'if (var < const)'". + * This is the only variable-size bpf_ringbuf_output path in this module; + * bpf_ringbuf_reserve paths use a fixed sizeof(...) only. + */ + const __u32 max_bytes = sizeof(struct socket_data_event_t); + __u32 nbytes; + if (size > max_bytes) { + nbytes = max_bytes; + } else { + nbytes = (__u32)size; + } + u32 shard = bpf_get_smp_processor_id() & (SOCKET_DATA_RINGBUF_SHARDS - 1); switch (shard) { - case 0: return bpf_ringbuf_output(&socket_data_events_0, data, size, 0); - case 1: return bpf_ringbuf_output(&socket_data_events_1, data, size, 0); - case 2: return bpf_ringbuf_output(&socket_data_events_2, data, size, 0); - case 3: return bpf_ringbuf_output(&socket_data_events_3, data, size, 0); - case 4: return bpf_ringbuf_output(&socket_data_events_4, data, size, 0); - case 5: return bpf_ringbuf_output(&socket_data_events_5, data, size, 0); - case 6: return bpf_ringbuf_output(&socket_data_events_6, data, size, 0); - case 7: return bpf_ringbuf_output(&socket_data_events_7, data, size, 0); - default: return bpf_ringbuf_output(&socket_data_events_0, data, size, 0); + case 0: return bpf_ringbuf_output(&socket_data_events_0, data, nbytes, 0); + case 1: return bpf_ringbuf_output(&socket_data_events_1, data, nbytes, 0); + case 2: return bpf_ringbuf_output(&socket_data_events_2, data, nbytes, 0); + case 3: return bpf_ringbuf_output(&socket_data_events_3, data, nbytes, 0); + case 4: return bpf_ringbuf_output(&socket_data_events_4, data, nbytes, 0); + case 5: return bpf_ringbuf_output(&socket_data_events_5, data, nbytes, 0); + case 6: return bpf_ringbuf_output(&socket_data_events_6, data, nbytes, 0); + case 7: return bpf_ringbuf_output(&socket_data_events_7, data, nbytes, 0); + default: return bpf_ringbuf_output(&socket_data_events_0, data, nbytes, 0); } } @@ -1020,7 +1052,7 @@ static __noinline void process_syscall_data(struct pt_regs* ctx, increment_counter(&socket_data_submit_total); } long ret = output_to_data_shard(socket_data_event, - sizeof(struct socket_data_event_t) - MAX_MSG_SIZE + size_to_save); + socket_data_event_output_len(size_to_save)); if (ret != 0 && log_socket_data_submit_stats) { increment_counter(&socket_data_submit_failed_total); } From 1f33082ccf4af5e706b5fb06b5fa78ba5c4bce15 Mon Sep 17 00:00:00 2001 From: notshivansh Date: Thu, 14 May 2026 22:42:05 +0530 Subject: [PATCH 4/7] fix ? --- ebpf/kernel/module.bpf.c | 93 ++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 04f40a0d..7bf2a216 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -674,11 +674,17 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, } } + /* + * sock_alloc_socket path: only set socketConn after we fully populate from sk. + * On bpf_probe_read_kernel failure, sk NULL, or non-INET family, do not return — + * otherwise conn_info_map is never updated and recvfrom/writev see conn_info_map + * misses (trace: "sock alloc found, processing" without ipv4/processed lines). + * Fall through to user sockaddr or ip/port=0 registration like accept(NULL). + */ if (args.sock_alloc_socket != NULL) { if (print_bpf_logs) { bpf_printk("sock alloc found, processing"); } - socketConn = true; /* * Read struct sock* from struct socket without CO-RE. @@ -689,42 +695,49 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, */ struct akto_socket sock_hdr = {}; if (bpf_probe_read_kernel(&sock_hdr, sizeof(sock_hdr), - args.sock_alloc_socket) != 0) - return; - struct sock* sk = (struct sock *)(unsigned long)sock_hdr.sk; + args.sock_alloc_socket) == 0) { + struct sock* sk = (struct sock *)(unsigned long)sock_hdr.sk; - if (sk == NULL) - return; - - /* struct sock CO-RE relocations succeed normally on this kernel. */ - uint16_t family = BPF_CORE_READ(sk, __sk_common.skc_family); - conn_info.port = BPF_CORE_READ(sk, __sk_common.skc_dport); - lport = BPF_CORE_READ(sk, __sk_common.skc_num); + if (sk != NULL) { + uint16_t family = BPF_CORE_READ(sk, __sk_common.skc_family); - if (family == AF_INET) { - if (print_bpf_logs) { - bpf_printk("sock alloc found ipv4, processing"); - } - conn_info.ip = BPF_CORE_READ(sk, __sk_common.skc_daddr); - srcIp = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); - } else if (family == AF_INET6) { - if (print_bpf_logs) { - bpf_printk("sock alloc found ipv6, processing"); - } - __u8 v6_dst[16] = {}; - __u8 v6_src[16] = {}; - if (bpf_core_field_exists(sk->__sk_common.skc_v6_daddr)) { - bpf_core_read(v6_dst, sizeof(v6_dst), - &sk->__sk_common.skc_v6_daddr); - bpf_core_read(v6_src, sizeof(v6_src), - &sk->__sk_common.skc_v6_rcv_saddr); + if (family == AF_INET) { + if (print_bpf_logs) { + bpf_printk("sock alloc found ipv4, processing"); + } + conn_info.port = BPF_CORE_READ(sk, __sk_common.skc_dport); + lport = BPF_CORE_READ(sk, __sk_common.skc_num); + conn_info.ip = BPF_CORE_READ(sk, __sk_common.skc_daddr); + srcIp = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr); + socketConn = true; + } else if (family == AF_INET6) { + if (print_bpf_logs) { + bpf_printk("sock alloc found ipv6, processing"); + } + conn_info.port = BPF_CORE_READ(sk, __sk_common.skc_dport); + lport = BPF_CORE_READ(sk, __sk_common.skc_num); + __u8 v6_dst[16] = {}; + __u8 v6_src[16] = {}; + if (bpf_core_field_exists(sk->__sk_common.skc_v6_daddr)) { + bpf_core_read(v6_dst, sizeof(v6_dst), + &sk->__sk_common.skc_v6_daddr); + bpf_core_read(v6_src, sizeof(v6_src), + &sk->__sk_common.skc_v6_rcv_saddr); + } + conn_info.ip = ((__u32 *)v6_dst)[3]; + srcIp = ((__u32 *)v6_src)[3]; + socketConn = true; + } else if (print_bpf_logs) { + bpf_printk("sock alloc skip non-inet family: %d", family); + } + } else if (print_bpf_logs) { + bpf_printk("sock alloc sk NULL after hdr read"); } - conn_info.ip = ((__u32 *)v6_dst)[3]; - srcIp = ((__u32 *)v6_src)[3]; - } else { - return; + } else if (print_bpf_logs) { + bpf_printk("sock alloc bpf_probe_read_kernel(socket hdr) failed"); } - if (print_bpf_logs) { + + if (socketConn && print_bpf_logs) { bpf_printk("sock alloc found, processed: id: %llu ip: %llu port: %d", id, conn_info.ip, conn_info.port); bpf_printk("sock alloc found, processed: id: %llu srcIp: %llu srcPort: %d", @@ -1290,8 +1303,9 @@ int syscall__probe_ret_writev(struct pt_regs* ctx) { } struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ - if (write_args != NULL && write_args->sock_event) { + /* No sock_event gate: rely on conn_info_map in process_syscall_data (matches send/sendto/recvmsg paths). + * security_socket_sendmsg can miss ordering on some kernels, which would drop all write(2) payloads. */ + if (write_args != NULL) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_writev data process: pid: %d", id); } @@ -1384,8 +1398,7 @@ int syscall__probe_ret_readv(struct pt_regs* ctx) { } struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ - if (read_args != NULL && read_args->sock_event) { + if (read_args != NULL) { process_syscall_data_vecs(ctx, read_args, id, false); } @@ -1564,8 +1577,7 @@ int syscall__probe_ret_read(struct pt_regs* ctx) { struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ - if (read_args != NULL && read_args->sock_event) { + if (read_args != NULL) { process_syscall_data(ctx, read_args, id, false, false); } @@ -1698,8 +1710,7 @@ int syscall__probe_ret_write(struct pt_regs* ctx) { struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ - if (write_args != NULL && write_args->sock_event) { + if (write_args != NULL) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_write data process: pid: %d", id); } From 3fb7d3405305cdb47102a62e47fcf21281f1fc12 Mon Sep 17 00:00:00 2001 From: notshivansh Date: Fri, 15 May 2026 00:48:46 +0530 Subject: [PATCH 5/7] telemetry and revert some bpf c code --- ebpf/bpfwrapper/eventCallbacks.go | 43 ++++++++++----------- ebpf/kernel/module.bpf.c | 14 ++++--- trafficUtil/kafkaUtil/parser.go | 63 +++++++++++++++---------------- 3 files changed, 61 insertions(+), 59 deletions(-) diff --git a/ebpf/bpfwrapper/eventCallbacks.go b/ebpf/bpfwrapper/eventCallbacks.go index d75e8872..da286ea9 100644 --- a/ebpf/bpfwrapper/eventCallbacks.go +++ b/ebpf/bpfwrapper/eventCallbacks.go @@ -2,6 +2,7 @@ package bpfwrapper import ( "log/slog" + "sync/atomic" "time" "unsafe" @@ -30,6 +31,9 @@ var ( func init() { metaUtils.InitVar("TRAFFIC_IGNORE_DEFAULT_PORTS", &ignorePorts) + if metaUtils.TrafficLogBpfSocketDataSubmits { + startSocketDataInboundMetricsFlushLoop() + } } func SocketOpenEventCallback(data []byte, connectionFactory *connections.Factory) { @@ -74,32 +78,29 @@ func SocketCloseEventCallback(data []byte, connectionFactory *connections.Factor const socketDataInboundLogInterval = 10 * time.Second -var ( - socketDataInboundCount uint64 - socketDataInboundLastLog time.Time -) +var socketDataInboundEvents atomic.Uint64 + +func startSocketDataInboundMetricsFlushLoop() { + go func() { + ticker := time.NewTicker(socketDataInboundLogInterval) + defer ticker.Stop() + for range ticker.C { + n := socketDataInboundEvents.Swap(0) + if n == 0 { + continue + } + slog.Warn("socket_data events reaching eventCallback", + "countInWindow", n, + "window", socketDataInboundLogInterval.String()) + } + }() +} func noteSocketDataInboundBeforeSend() { - if !metaUtils.TrafficLogBpfSocketDataSubmits { return } - - socketDataInboundCount++ - now := time.Now() - if socketDataInboundLastLog.IsZero() { - socketDataInboundLastLog = now - return - } - d := now.Sub(socketDataInboundLastLog) - if d < socketDataInboundLogInterval { - return - } - slog.Warn("socket_data events reaching eventCallback", - "countInWindow", socketDataInboundCount, - "window", d.String()) - socketDataInboundCount = 0 - socketDataInboundLastLog = now + socketDataInboundEvents.Add(1) } // eventAttributesLogicalSize is the C-side offset of the msg field in socket_data_event_t. diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 7bf2a216..9efdeac0 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -1303,9 +1303,8 @@ int syscall__probe_ret_writev(struct pt_regs* ctx) { } struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - /* No sock_event gate: rely on conn_info_map in process_syscall_data (matches send/sendto/recvmsg paths). - * security_socket_sendmsg can miss ordering on some kernels, which would drop all write(2) payloads. */ - if (write_args != NULL) { + /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ + if (write_args != NULL && write_args->sock_event) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_writev data process: pid: %d", id); } @@ -1398,7 +1397,8 @@ int syscall__probe_ret_readv(struct pt_regs* ctx) { } struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { + /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ + if (read_args != NULL && read_args->sock_event) { process_syscall_data_vecs(ctx, read_args, id, false); } @@ -1577,7 +1577,8 @@ int syscall__probe_ret_read(struct pt_regs* ctx) { struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { + /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ + if (read_args != NULL && read_args->sock_event) { process_syscall_data(ctx, read_args, id, false, false); } @@ -1710,7 +1711,8 @@ int syscall__probe_ret_write(struct pt_regs* ctx) { struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args != NULL) { + /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ + if (write_args != NULL && write_args->sock_event) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_write data process: pid: %d", id); } diff --git a/trafficUtil/kafkaUtil/parser.go b/trafficUtil/kafkaUtil/parser.go index 58b87bb6..7d34fc3e 100644 --- a/trafficUtil/kafkaUtil/parser.go +++ b/trafficUtil/kafkaUtil/parser.go @@ -13,6 +13,7 @@ import ( "os" "strings" "sync" + "sync/atomic" "time" "github.com/akto-api-security/mirroring-api-logging/trafficUtil/apiProcessor" @@ -274,11 +275,9 @@ var ( currentBandwidthProcessed = 0 lastSampleUpdate = time.Now().Unix() sampleMutex = sync.RWMutex{} - parserMetricsMutex = sync.Mutex{} - parserEventsInWindow uint64 - parserReceiveBytesWindow uint64 - parserSentBytesWindow uint64 - lastParserMetricsLog time.Time + parserEventsAtomic atomic.Uint64 + parserReceiveBytesAtomic atomic.Uint64 + parserSentBytesAtomic atomic.Uint64 injectTagsMap = map[string]string{} methodsMap = map[string]bool{ "GET": true, @@ -301,7 +300,7 @@ var ( bloomFilterFPRate = 0.01 timeBucketDuration = 10 * time.Minute memSamplingEnabled = false - parserMetricsEnabled = false + parserMetricsEnabled = true ) var bloomFilter *bloomfilter.BloomFilter @@ -310,33 +309,30 @@ const ONE_MINUTE = 60 const parserMetricsInterval = 10 * time.Second func noteParserEvent(receiveBytes int, sentBytes int) { - parserMetricsMutex.Lock() - defer parserMetricsMutex.Unlock() - - parserEventsInWindow++ - parserReceiveBytesWindow += uint64(receiveBytes) - parserSentBytesWindow += uint64(sentBytes) - - now := time.Now() - if lastParserMetricsLog.IsZero() { - lastParserMetricsLog = now - return - } - - if now.Sub(lastParserMetricsLog) < parserMetricsInterval { - return - } + parserEventsAtomic.Add(1) + parserReceiveBytesAtomic.Add(uint64(receiveBytes)) + parserSentBytesAtomic.Add(uint64(sentBytes)) +} - slog.Warn("parser events received", - "countInWindow", parserEventsInWindow, - "window", now.Sub(lastParserMetricsLog).String(), - "receiveBytesInWindow", parserReceiveBytesWindow, - "sentBytesInWindow", parserSentBytesWindow, - ) - parserEventsInWindow = 0 - parserReceiveBytesWindow = 0 - parserSentBytesWindow = 0 - lastParserMetricsLog = now +func startParserMetricsFlushLoop() { + go func() { + ticker := time.NewTicker(parserMetricsInterval) + defer ticker.Stop() + for range ticker.C { + events := parserEventsAtomic.Swap(0) + recv := parserReceiveBytesAtomic.Swap(0) + sent := parserSentBytesAtomic.Swap(0) + if events == 0 && recv == 0 && sent == 0 { + continue + } + slog.Warn("parser events received", + "countInWindow", events, + "window", parserMetricsInterval.String(), + "receiveBytesInWindow", recv, + "sentBytesInWindow", sent, + ) + } + }() } func init() { @@ -350,6 +346,9 @@ func init() { utils.InitVar("TIME_BUCKET_DURATION_MINUTES", &timeBucketDuration) utils.InitVar("DATA_PRINT_MODE", &dataPrintMode) utils.InitVar("TRAFFIC_PARSER_METRICS_ENABLED", &parserMetricsEnabled) + if parserMetricsEnabled { + startParserMetricsFlushLoop() + } if outputBandwidthLimitPerMin != -1 { outputBandwidthLimitPerMin = outputBandwidthLimitPerMin * 1024 * 1024 From b2ed5fb507099faa667bbff57c7d178eeea8803c Mon Sep 17 00:00:00 2001 From: notshivansh Date: Fri, 15 May 2026 01:31:34 +0530 Subject: [PATCH 6/7] print static map details once only --- ebpf/main.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ebpf/main.go b/ebpf/main.go index 7dd3aabd..193eabd4 100644 --- a/ebpf/main.go +++ b/ebpf/main.go @@ -256,9 +256,6 @@ func startEBPFMapMemoryReporter(coll *ebpf.Collection) { return } - interval := 120 * time.Second - trafficUtils.InitVar("TRAFFIC_EBPF_MAP_MEMORY_INTERVAL", &interval) - // Ringbufs, per-CPU scratch buffers, and maps with large values or // many entries — omit single-slot counters/flags and small pointer maps. mapNames := []string{ @@ -282,13 +279,6 @@ func startEBPFMapMemoryReporter(coll *ebpf.Collection) { } logEBPFMapMemorySnapshot(coll, mapNames) - go func() { - ticker := time.NewTicker(interval) - defer ticker.Stop() - for range ticker.C { - logEBPFMapMemorySnapshot(coll, mapNames) - } - }() } func logEBPFMapMemorySnapshot(coll *ebpf.Collection, mapNames []string) { From c7a5b54d2c6ceb85c3525ad0c8ac093bf7be8c0e Mon Sep 17 00:00:00 2001 From: notshivansh Date: Fri, 22 May 2026 12:33:22 +0530 Subject: [PATCH 7/7] only check self memory --- ebpf-run.sh | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/ebpf-run.sh b/ebpf-run.sh index ca73af54..ff019bbc 100644 --- a/ebpf-run.sh +++ b/ebpf-run.sh @@ -2,7 +2,7 @@ # # MEM_LIMIT (optional): memory cap in integer MiB (mebibytes, 1024-based "MB"). # When set, it overrides cgroup/host detection for MEM_LIMIT_MB and drives -# GOMEMLIMIT, cgroup % kill, and Akto AKTO_MEM_* exports below. +# GOMEMLIMIT, process RSS % kill, and Akto AKTO_MEM_* exports below. # Example: 52 GiB cap -> MEM_LIMIT=53248 (52 * 1024). # Omit MEM_LIMIT to auto-detect from cgroup memory.max (Docker/K8s) or host RAM. # @@ -16,7 +16,7 @@ LOG_FILE=${LOG_FILE:-/tmp/dump.log} MAX_LOG_SIZE=${MAX_LOG_SIZE:-10485760} # Default to 10 MB if not set (10 MB = 10 * 1024 * 1024 bytes) CHECK_INTERVAL=${CHECK_INTERVAL:-60} CHECK_INTERVAL_MEM=${CHECK_INTERVAL_MEM:-5} # Check interval in seconds (configurable via env) -MEMORY_THRESHOLD=${MEMORY_THRESHOLD:-85} # Kill process at this % memory usage (configurable via env) +MEMORY_THRESHOLD=${MEMORY_THRESHOLD:-85} # Kill ebpf-logging when its RSS reaches this % of MEM_LIMIT (configurable via env) GOMEMLIMIT_PERCENT=${GOMEMLIMIT_PERCENT:-60} # GOMEMLIMIT as % of container memory limit (configurable via env) AKTO_SUPPRESS_TRACE=${AKTO_SUPPRESS_TRACE:-true} CRASH_RESTART_BACKOFF_SECONDS=${CRASH_RESTART_BACKOFF_SECONDS:-10} @@ -45,35 +45,25 @@ rotate_log() { fi } -# Function to check memory usage and kill process if threshold exceeded +# Function to check ebpf-logging RSS and kill if threshold exceeded check_memory_and_kill() { - # Resolve container's cgroup path (needed when hostPID: true shifts cgroup root) - CGROUP_BASE=$(cut -d: -f3 /proc/self/cgroup | head -1) - - # Get current memory usage in bytes - if [ -f "/sys/fs/cgroup${CGROUP_BASE}/memory.current" ]; then - # cgroup v2 with hostPID - CURRENT_MEM=$(cat "/sys/fs/cgroup${CGROUP_BASE}/memory.current") - elif [ -f /sys/fs/cgroup/memory.current ]; then - # cgroup v2 normal - CURRENT_MEM=$(cat /sys/fs/cgroup/memory.current) - elif [ -f "/sys/fs/cgroup${CGROUP_BASE}/memory.usage_in_bytes" ]; then - # cgroup v1 with hostPID - CURRENT_MEM=$(cat "/sys/fs/cgroup${CGROUP_BASE}/memory.usage_in_bytes") - elif [ -f /sys/fs/cgroup/memory/memory.usage_in_bytes ]; then - # cgroup v1 normal - CURRENT_MEM=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes) - else + CURRENT_MEM=0 + for pid in $(pgrep -x ebpf-logging 2>/dev/null); do + rss_kb=$(awk '/^VmRSS:/ {print $2; exit}' "/proc/$pid/status" 2>/dev/null) || continue + [ -n "$rss_kb" ] || continue + CURRENT_MEM=$((CURRENT_MEM + rss_kb * 1024)) + done + + if [ "$CURRENT_MEM" -eq 0 ]; then return fi - # Calculate percentage used PERCENT_USED=$((CURRENT_MEM * 100 / MEM_LIMIT_BYTES)) - echo "Memory usage: ${PERCENT_USED}% (${CURRENT_MEM} / ${MEM_LIMIT_BYTES} bytes)" + echo "ebpf-logging memory usage: ${PERCENT_USED}% (${CURRENT_MEM} / ${MEM_LIMIT_BYTES} bytes)" if [ "$PERCENT_USED" -ge "$MEMORY_THRESHOLD" ]; then - echo "Memory threshold ${MEMORY_THRESHOLD}% exceeded (${PERCENT_USED}%), killing ebpf-logging process" + echo "ebpf-logging memory threshold ${MEMORY_THRESHOLD}% exceeded (${PERCENT_USED}%), killing process" pkill -9 ebpf-logging fi }