diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 196078b..a17a125 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -1,117 +1,20 @@ -/* - * module.bpf.c — libbpf/CO-RE eBPF kernel program. - * - * Compiled ahead-of-time with bpf2go; no BCC or host kernel headers required. - * vmlinux.h provides all kernel types from the running kernel's BTF data. - */ - -#include "vmlinux.h" - -#include -#include -#include - -/* - * Some vmlinux.h builds drag in kernel helper headers that define bpf_printk. - * Undefine it so bpf_helpers.h can install its modern variadic version cleanly. - */ -#ifdef bpf_printk -#undef bpf_printk -#endif - -/* AF_INET / AF_INET6 are preprocessor constants not captured by BTF. */ -#ifndef AF_INET -#define AF_INET 2 -#endif -#ifndef AF_INET6 -#define AF_INET6 10 -#endif - - -#define bpf_printk(fmt, ...) \ -({ \ - char ____fmt[] = fmt; \ - bpf_trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ -}) - -/* - * Map bpf2go target defines to the custom arch macros used throughout this file. - * bpf2go sets __TARGET_ARCH_x86 for amd64 and __TARGET_ARCH_arm64 for arm64. - */ -#if defined(__TARGET_ARCH_x86) || defined(__x86_64__) - #define TARGET_ARCH_X86_64 -#elif defined(__TARGET_ARCH_arm64) || defined(__aarch64__) - #define TARGET_ARCH_AARCH64 -#endif - -/* - * Portable syscall-argument accessors. - * - * On both x86-64 and ARM64, the kernel syscall wrapper has the signature: - * asmlinkage long __x64_sys_xxx(const struct pt_regs *regs) // x86-64 - * asmlinkage long __arm64_sys_xxx(const struct pt_regs *regs) // ARM64 - * - * PT_REGS_PARM1(ctx) gives us that 'regs' pointer (the wrapper's argument). - * PT_REGS_PARM1_CORE_SYSCALL is supposed to dereference it, but older libbpf - * versions define it as a simple BPF_CORE_READ(ctx, di/regs[0]) — i.e. it - * returns the pointer value itself, not the actual syscall argument. - * Casting that 64-bit kernel address to int gives garbage fd values. - * - * Fix: explicitly dereference the inner pt_regs using the correct field names - * for each architecture (di/si/dx on x86-64, regs[0/1/2] on ARM64). - */ -#ifdef TARGET_ARCH_AARCH64 - #define SYSCALL_PARM1(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), regs[0]) - #define SYSCALL_PARM2(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), regs[1]) - #define SYSCALL_PARM3(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), regs[2]) -#elif defined(TARGET_ARCH_X86_64) - #define SYSCALL_PARM1(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), di) - #define SYSCALL_PARM2(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), si) - #define SYSCALL_PARM3(ctx) \ - BPF_CORE_READ((const struct pt_regs *)PT_REGS_PARM1(ctx), dx) -#else - #define SYSCALL_PARM1(ctx) PT_REGS_PARM1_CORE_SYSCALL(ctx) - #define SYSCALL_PARM2(ctx) PT_REGS_PARM2_CORE_SYSCALL(ctx) - #define SYSCALL_PARM3(ctx) PT_REGS_PARM3_CORE_SYSCALL(ctx) -#endif - -/* - * BPF global read-only variable — set from userspace via CollectionSpec before loading. - * Replaces the runtime Go string-substitution used in the BCC version. - */ -volatile const bool print_bpf_logs = false; - -/* - * CHUNK_SIZE_LIMIT must be a compile-time constant because it is used as the - * bound of a #pragma-unrolled loop (the BPF verifier requires statically known - * loop counts). Override at build time via bpf2go cflags: -DCHUNK_SIZE_LIMIT= - */ -#ifndef CHUNK_SIZE_LIMIT -#define CHUNK_SIZE_LIMIT 4 -#endif - +#include +#include +#include +#include +#include +#include + +#define socklen_t size_t #define MAX_MSG_SIZE 30720 -#define CHUNK_LIMIT CHUNK_SIZE_LIMIT -#define LOOP_LIMIT 42 - -/* - * Default connection map size. The Go loader can resize individual maps via - * CollectionSpec.Maps[name].MaxEntries before calling LoadAndAssign. - */ -#define TRAFFIC_MAX_CONNECTION_MAP_SIZE 131072 - -char LICENSE[] SEC("license") = "GPL"; +#define CHUNK_LIMIT CHUNK_SIZE_LIMIT +#define LOOP_LIMIT 42 -/* =================================================================== - * Enums - * =================================================================== */ +#define ARCH_TYPE 1 enum source_function_t { + + // For syscalls. kSyscallAccept, kSyscallConnect, kSyscallClose, @@ -128,16 +31,15 @@ enum source_function_t { kSyscallWriteV, kSyscallReadV, kSyscallSendfile, + + // For SSL libraries. kSSLWrite, kSSLRead, + kGoTLSWrite, kGoTLSRead }; -/* =================================================================== - * User-defined structs (layout must stay in sync with structs/structs.go) - * =================================================================== */ - struct conn_info_t { u64 id; u32 fd; @@ -149,64 +51,10 @@ struct conn_info_t { u32 writeEventsCount; }; -/* - * Plain-C mirrors of the sockaddr family structs. - * - * These are intentionally NOT from vmlinux.h so they carry no - * preserve_access_index attribute and generate zero CO-RE relocations. - * All sockaddr data arrives from user space and is read with - * bpf_probe_read_user(), so we never need CO-RE portability for these. - */ -struct akto_sockaddr { - unsigned short sa_family; - char sa_data[14]; -}; - -struct akto_sockaddr_in { - unsigned short sin_family; - unsigned short sin_port; /* big-endian */ - unsigned int sin_addr; /* s_addr, big-endian */ - unsigned char _pad[8]; -}; - -struct akto_sockaddr_in6 { - unsigned short sin6_family; - unsigned short sin6_port; /* big-endian */ - unsigned int sin6_flowinfo; - unsigned char sin6_addr[16]; - unsigned int sin6_scope_id; -}; - -/* - * Plain-C mirror of the first fields of struct socket (no preserve_access_index). - * - * CO-RE relocations for struct socket::sk consistently fail at load time with - * 0xbad2310 ("bad relo") on the target kernel even though bpf_core_field_exists() - * returns 1 for the same field. This is the same class of issue described in - * cilium/ebpf#1031: the FIELD_EXISTS and FIELD_BYTE_OFFSET relocation types are - * resolved from different BTF scopes (vmlinux vs. module BTF), producing an - * inconsistent result. - * - * The fix follows the same pattern used for akto_sockaddr*: define a plain C - * struct that mirrors the kernel layout and use bpf_probe_read_kernel — no CO-RE - * relocation is generated, the compile-time offsetof() is correct because - * vmlinux.h is regenerated from the *running* kernel by `make generate`. - * - * Layout of struct socket (stable across all 64-bit kernels we support): - * offset 0: state (socket_state enum, 4 bytes) - * offset 4: type (short, 2 bytes) - * offset 6: _pad (2 bytes) - * offset 8: flags (unsigned long, 8 bytes) - * offset 16: file (struct file *, 8 bytes) - * offset 24: sk (struct sock *, 8 bytes) ← what we need - */ -struct akto_socket { - __u32 state; - __u16 type; - __u16 _pad; - __u64 flags; - __u64 file; - __u64 sk; /* struct sock * stored as u64 to avoid CO-RE on the pointer type */ +union sockaddr_t { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; }; struct accept_args_t { @@ -263,230 +111,44 @@ struct socket_data_event_t { char msg[MAX_MSG_SIZE]; }; -/* =================================================================== - * BPF maps — BTF-typed declarations replacing BCC macros - * =================================================================== */ - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, TRAFFIC_MAX_CONNECTION_MAP_SIZE); - __type(key, u64); - __type(value, struct conn_info_t); -} conn_info_map SEC(".maps"); - +BPF_HASH(conn_info_map, u64, struct conn_info_t, TRAFFIC_MAX_CONNECTION_MAP_SIZE); // 128 * 1024 /* - * conn_info_map_keys: rotating ring of active conn_info_map keys. - * BPF array keys are always u32 (array index); value is the u64 tgid_fd. - */ -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __uint(max_entries, TRAFFIC_MAX_CONNECTION_MAP_SIZE); - __type(key, u32); - __type(value, u64); -} conn_info_map_keys SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __uint(max_entries, 1); - __type(key, u32); - __type(value, int); -} conn_counter SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, 64 * 1024 * 1024); -} socket_data_events SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, 1024 * 1024); -} socket_open_events SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_RINGBUF); - __uint(max_entries, 1024 * 1024); -} socket_close_events SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(max_entries, 1); - __type(key, u32); - __type(value, struct socket_data_event_t); -} socket_data_event_buffer_heap SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct accept_args_t); -} active_accept_args_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct close_args_t); -} active_close_args_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct data_args_t); -} active_read_args_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct data_args_t); -} active_write_args_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct data_args_t); -} active_ssl_read_args_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, struct data_args_t); -} active_ssl_write_args_map SEC(".maps"); - -/* =================================================================== - * Node.js TLS structs and maps - * =================================================================== */ +Stores conn_info_map's keys on a rotating basic, using the conn_counter. +i.e. clear the one which you're on and store the new one. +*/ +BPF_ARRAY(conn_info_map_keys, u64, TRAFFIC_MAX_CONNECTION_MAP_SIZE); +BPF_ARRAY(conn_counter, int, 1); -struct node_tlswrap_symaddrs_t { - u32 TLSWrapStreamListenerOffset; - u32 StreamListenerStreamOffset; - u32 StreamBaseStreamResourceOffset; - u32 LibuvStreamWrapStreamBaseOffset; - u32 LibuvStreamWrapStreamOffset; - u32 UVStreamSIOWatcherOffset; - u32 UVIOSFDOffset; -}; +BPF_PERF_OUTPUT(socket_data_events); +BPF_PERF_OUTPUT(socket_open_events); +BPF_PERF_OUTPUT(socket_close_events); -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 1024); - __type(key, u32); - __type(value, struct node_tlswrap_symaddrs_t); -} node_tlswrap_symaddrs_map SEC(".maps"); +BPF_PERCPU_ARRAY(socket_data_event_buffer_heap, struct socket_data_event_t, 1); -/* - * active_TLSWrap_memfn_this: stores void* (tls_wrap pointer) per pid_tgid. - * void* cannot be a BTF map value type; stored as __u64. - */ -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, u64); - __type(value, __u64); -} active_TLSWrap_memfn_this SEC(".maps"); +BPF_HASH(active_accept_args_map, u64, struct accept_args_t); +BPF_HASH(active_close_args_map, u64, struct close_args_t); +BPF_HASH(active_read_args_map, u64, struct data_args_t); +BPF_HASH(active_write_args_map, u64, struct data_args_t); +BPF_HASH(active_ssl_read_args_map, uint64_t, struct data_args_t); +BPF_HASH(active_ssl_write_args_map, uint64_t, struct data_args_t); /* - * node_ssl_tls_wrap_map: ssl* → tls_wrap* mapping. - * Both pointers stored as __u64. - */ -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, __u64); - __type(value, __u64); -} node_ssl_tls_wrap_map SEC(".maps"); - -/* =================================================================== - * Go TLS structs and maps - * =================================================================== */ +Maintain a map of kubernetes pids, and only process, if data is from them. +This should reduce the noise a lot. +*/ -struct tgid_goid_t { - u32 tgid; - long long goid; -}; - -struct go_tls_conn_args { - void* conn_ptr; - char* plaintext_ptr; -}; - -struct go_interface { - int64_t type; - void* ptr; -}; -enum location_type_t { - kLocationTypeStack = 1, - kLocationTypeRegisters = 2 -}; - -struct location_t { - enum location_type_t type; - u32 offset; -}; - -struct go_symaddrs_t { - u64 FDSysFDOffset; - u64 TLSConnOffset; - u64 GIDOffset; - u64 TCPConnOffset; - u64 IsClientOffset; - - struct location_t WriteConnectionLoc; - struct location_t WriteBufferLoc; - struct location_t WriteRet0Loc; - struct location_t WriteRet1Loc; - - struct location_t ReadConnectionLoc; - struct location_t ReadBufferLoc; - struct location_t ReadRet0Loc; - 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); - __type(key, u32); - __type(value, struct go_symaddrs_t); -} go_symaddrs_table SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 65536); - __type(key, struct tgid_goid_t); - __type(value, struct go_tls_conn_args); -} active_tls_conn_op_map SEC(".maps"); - -/* =================================================================== - * Helper functions - * =================================================================== */ - -static __always_inline u64 gen_tgid_fd(u32 tgid, int fd) { +static __inline u64 gen_tgid_fd(u32 tgid, int fd) { return ((u64)tgid << 32) | (u32)fd; } -static __always_inline void process_syscall_accept(struct pt_regs* ctx, - const struct accept_args_t* args, - u64 id, bool isConnect) { - int ret_fd = PT_REGS_RC(ctx); +static __inline void process_syscall_accept(struct pt_regs* ret, const struct accept_args_t* args, u64 id, bool isConnect) { + int ret_fd = PT_REGS_RC(ret); - if (!isConnect && ret_fd < 0) { + if(!isConnect && ret_fd < 0){ return; } + union sockaddr_t* addr; struct conn_info_t conn_info = {}; bool socketConn = false; @@ -494,183 +156,143 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, u32 srcIp = 0; uint16_t lport = 0; - if (args->addr != NULL) { - if (print_bpf_logs) { - bpf_printk("sock addr found, processing"); - } + if(args->addr != NULL){ + if (PRINT_BPF_LOGS){ + bpf_trace_printk("sock addr found, processing"); + } + addr = (union sockaddr_t*)args->addr; } - - if (args->sock_alloc_socket != NULL) { - if (print_bpf_logs) { - bpf_printk("sock alloc found, processing"); - } + if(args->sock_alloc_socket !=NULL){ + if (PRINT_BPF_LOGS){ + bpf_trace_printk("sock alloc found, processing"); + } socketConn = true; - - /* - * Read struct sock* from struct socket without CO-RE. - * BPF_CORE_READ on struct socket::sk fails with 0xbad2310 on this - * kernel even though bpf_core_field_exists() says the field exists — - * the two relocation types use different BTF resolution paths (cilium/ebpf#1031). - * akto_socket mirrors the stable first-field layout; no CO-RE is generated. - */ - 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; - - 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); - + struct sock* sk = NULL; + bpf_probe_read_kernel(&sk, sizeof(sk), &(args->sock_alloc_socket)->sk); + struct sock_common* sk_common = &sk->__sk_common; + uint16_t family = -1; + uint16_t rport = -1; + u32 ip = 0; + bpf_probe_read_kernel(&family, sizeof(family), &sk_common->skc_family); + bpf_probe_read_kernel(&rport, sizeof(rport), &sk_common->skc_dport); + bpf_probe_read_kernel(&lport, sizeof(lport), &sk_common->skc_num); + conn_info.port = rport; 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); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("sock alloc found ipv4, processing"); + } + bpf_probe_read_kernel(&(conn_info.ip), sizeof(conn_info.ip), &sk_common->skc_daddr); + bpf_probe_read_kernel(&(srcIp), sizeof(srcIp), &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); - } - conn_info.ip = ((__u32 *)v6_dst)[3]; - srcIp = ((__u32 *)v6_src)[3]; + if (PRINT_BPF_LOGS){ + bpf_trace_printk("sock alloc found ipv6, processing"); + } + struct in6_addr in_addr; + struct in6_addr in_addr_2; + bpf_probe_read_kernel(&(in_addr), sizeof(in_addr), &sk_common->skc_v6_daddr); + bpf_probe_read_kernel(&(in_addr_2), sizeof(in_addr_2), &sk_common->skc_v6_rcv_saddr); + conn_info.ip = (in_addr.s6_addr32)[3]; + srcIp = (in_addr_2.s6_addr32)[3]; } else { - return; + return; } - if (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", - id, srcIp, lport); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("sock alloc found, processed: id: %llu ip: %llu port: %d", id, conn_info.ip, conn_info.port); + bpf_trace_printk("sock alloc found, processed: id: %llu srcIp: %llu srcPort: %d", id, srcIp, lport); } } - if (!socketConn) { - if (args->addr != NULL) { - struct akto_sockaddr sa_hdr = {}; - 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) { - return; - } - } - // addr == NULL means accept(fd, NULL, NULL) — register the connection - // with ip/port=0 so data probes can find it in conn_info_map. + if ( !socketConn && addr->sa.sa_family != AF_INET && addr->sa.sa_family != AF_INET6 ) { + return; } conn_info.id = id; - if (isConnect) { + if(isConnect){ 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) { - struct akto_sockaddr sa_hdr = {}; - 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) { - 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) { - conn_info.port = sin6.sin6_port; - conn_info.ip = ((__u32 *)sin6.sin6_addr)[3]; - } - } + if(!socketConn){ + if ( addr->sa.sa_family == AF_INET ){ + struct sockaddr_in* sock_in = (struct sockaddr_in *)addr; + conn_info.port = sock_in->sin_port; + struct in_addr *in_addr_ptr = &(sock_in->sin_addr); + conn_info.ip = in_addr_ptr->s_addr; + } else { + struct sockaddr_in6* sock_in = (struct sockaddr_in6 *)addr; + conn_info.port = sock_in->sin6_port; + struct in6_addr *in_addr_ptr = &(sock_in->sin6_addr); + conn_info.ip = (in_addr_ptr->s6_addr32)[3]; + } } conn_info.ssl = false; + conn_info.readEventsCount = 0; conn_info.writeEventsCount = 0; u32 tgid = id >> 32; u64 tgid_fd = 0; - if (isConnect) { + if(isConnect){ tgid_fd = gen_tgid_fd(tgid, args->fd); } else { tgid_fd = gen_tgid_fd(tgid, ret_fd); } - u32 idx = 0; - int *counter = bpf_map_lookup_elem(&conn_counter, &idx); - int val = 0; - u32 val_key = 0; + int zero = 0; + int *counter = conn_counter.lookup_or_try_init(&zero, &zero); + int val = 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); - if (print_bpf_logs) { - bpf_printk("conn_info_counter reset: %d", *counter); - } + if ( (*counter) > ( TRAFFIC_MAX_CONNECTION_MAP_SIZE - 5 ) ) { + conn_counter.update(&zero,&zero); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("conn_info_counter reset: %d", *counter); } - (*counter)++; - val = *counter; - val_key = (u32)val; - if (print_bpf_logs) { - bpf_printk("conn_info_counter found: %d", val); - } - u64* curr = bpf_map_lookup_elem(&conn_info_map_keys, &val_key); - if (curr != NULL) { - u64 curVal = *curr; - struct conn_info_t* old_conn_info = bpf_map_lookup_elem(&conn_info_map, &curVal); - if (old_conn_info != NULL) { - bpf_map_delete_elem(&conn_info_map, &curVal); - if (print_bpf_logs) { - bpf_printk("conn_info_counter deleting: %d", curVal); - } - } + } + (*counter)++; + val = *counter; + if (PRINT_BPF_LOGS){ + bpf_trace_printk("conn_info_counter found: %d", val); + } + u64 *curr = conn_info_map_keys.lookup(&val); + if (curr != NULL) { + u64 curVal = *curr; + struct conn_info_t *conn_info = conn_info_map.lookup(&curVal); + if (conn_info != NULL) { + conn_info_map.delete(&curVal); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("conn_info_counter deleting: %d", curVal); + } } + } } - bpf_map_update_elem(&conn_info_map_keys, &val_key, &tgid_fd, BPF_ANY); - bpf_map_update_elem(&conn_info_map, &tgid_fd, &conn_info, BPF_ANY); + conn_info_map_keys.update(&val, &tgid_fd); + conn_info_map.update(&tgid_fd, &conn_info); struct socket_open_event_t socket_open_event = {}; - socket_open_event.id = conn_info.id; - socket_open_event.fd = conn_info.fd; + socket_open_event.id = conn_info.id; + socket_open_event.fd = conn_info.fd; socket_open_event.conn_start_ns = conn_info.conn_start_ns; - socket_open_event.port = conn_info.port; - socket_open_event.ip = conn_info.ip; - socket_open_event.src_ip = srcIp; - socket_open_event.src_port = lport; - - if (print_bpf_logs) { - bpf_printk("accept call: %llu %d %d", - socket_open_event.id, socket_open_event.fd, isConnect); - bpf_printk("accept call 2: %llu %d %d", - socket_open_event.ip, socket_open_event.port, isConnect); - bpf_printk("accept call 3: %llu %d %d", - socket_open_event.src_ip, socket_open_event.src_port, isConnect); + socket_open_event.port = conn_info.port; + socket_open_event.ip = conn_info.ip; + socket_open_event.src_ip = srcIp; + socket_open_event.src_port = lport; + + if (PRINT_BPF_LOGS){ + bpf_trace_printk("accept call: %llu %d %d", socket_open_event.id, socket_open_event.fd, isConnect); + bpf_trace_printk("accept call 2: %llu %d %d", socket_open_event.ip, socket_open_event.port, isConnect); + bpf_trace_printk("accept call 3: %llu %d %d", socket_open_event.src_ip, socket_open_event.src_port, isConnect); } socket_open_event.socket_open_ns = conn_info.conn_start_ns; - bpf_ringbuf_output(&socket_open_events, &socket_open_event, - sizeof(struct socket_open_event_t), 0); + socket_open_events.perf_submit(ret, &socket_open_event, sizeof(struct socket_open_event_t)); } -static __always_inline void process_syscall_close(struct pt_regs* ctx, - const struct close_args_t* args, - u64 id) { - int ret_val = PT_REGS_RC(ctx); +static __inline void process_syscall_close(struct pt_regs* ret, const struct close_args_t* args, u64 id) { + int ret_val = PT_REGS_RC(ret); if (ret_val < 0) { return; @@ -682,30 +304,27 @@ static __always_inline void process_syscall_close(struct pt_regs* ctx, 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); + struct conn_info_t* conn_info = conn_info_map.lookup(&tgid_fd); if (conn_info == NULL) { return; } struct socket_close_event_t socket_close_event = {}; - socket_close_event.id = conn_info->id; - socket_close_event.fd = conn_info->fd; + 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.port = conn_info->port; + socket_close_event.ip = conn_info->ip; socket_close_event.socket_close_ns = bpf_ktime_get_ns(); - bpf_ringbuf_output(&socket_close_events, &socket_close_event, - sizeof(struct socket_close_event_t), 0); - bpf_map_delete_elem(&conn_info_map, &tgid_fd); + socket_close_events.perf_submit(ret, &socket_close_event, sizeof(struct socket_close_event_t)); + conn_info_map.delete(&tgid_fd); } -static __always_inline void process_syscall_data(struct pt_regs* ctx, - const struct data_args_t* args, - u64 id, bool is_send, bool ssl) { - int bytes_exchanged = PT_REGS_RC(ctx); +static __inline void process_syscall_data(struct pt_regs* ret, const struct data_args_t* args, u64 id, bool is_send, bool ssl) { + int bytes_exchanged = PT_REGS_RC(ret); - if (args->iovlen > 0 && args->buf_size > 0) { + if(args->iovlen > 0 && args->buf_size > 0){ bytes_exchanged = args->buf_size; } @@ -713,8 +332,8 @@ static __always_inline void process_syscall_data(struct pt_regs* ctx, return; } - if (print_bpf_logs) { - bpf_printk("SSL data 1 %d", id); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("SSL data 1 %d", id); } if (args->fd < 0) { return; @@ -722,1532 +341,1436 @@ static __always_inline void process_syscall_data(struct pt_regs* ctx, u32 tgid = id >> 32; 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); + if (PRINT_BPF_LOGS){ + bpf_trace_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); + struct conn_info_t* conn_info = conn_info_map.lookup(&tgid_fd); if (conn_info == NULL) { return; } - if (print_bpf_logs) { - bpf_printk("SSL data 3 %d %llu %lu", id, tgid_fd, tgid); + if (PRINT_BPF_LOGS){ + bpf_trace_printk("SSL data 3 %d %llu %lu", id, tgid_fd, tgid); } - + if (conn_info->ssl != ssl) { return; } - if (print_bpf_logs) { - bpf_printk("SSL data 4 %llu %llu %d", id, tgid_fd, ssl); + if (PRINT_BPF_LOGS){ + bpf_trace_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); + struct socket_data_event_t* socket_data_event = socket_data_event_buffer_heap.lookup(&kZero); if (socket_data_event == NULL) { return; } - socket_data_event->id = conn_info->id; - socket_data_event->fd = conn_info->fd; + 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; + 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; + size_t size_to_save = 0; + int i =0; + #pragma unroll + for (i = 0; i < CHUNK_LIMIT; ++i) { + const int bytes_remaining = bytes_exchanged - bytes_sent; + + if (bytes_remaining <= 0) { + break; + } + size_t current_size = (bytes_remaining > MAX_MSG_SIZE && (i != CHUNK_LIMIT - 1)) ? MAX_MSG_SIZE : bytes_remaining; - int bytes_sent = 0; - u32 size_to_save = 0; - int i = 0; -#pragma unroll - for (i = 0; i < CHUNK_LIMIT; ++i) { - const int bytes_remaining = bytes_exchanged - bytes_sent; + size_t current_size_minus_1 = current_size - 1; + asm volatile("" : "+r"(current_size_minus_1) :); + current_size = current_size_minus_1 + 1; - if (bytes_remaining <= 0) { - break; - } - u32 current_size; - if (bytes_remaining > MAX_MSG_SIZE && (i != CHUNK_LIMIT - 1)) { - current_size = (u32)(MAX_MSG_SIZE - 1); - } else { - current_size = (u32)bytes_remaining; - } - if (current_size >= MAX_MSG_SIZE) { - current_size = (u32)(MAX_MSG_SIZE - 1); - } - current_size &= (u32)(MAX_MSG_SIZE - 1); /* verifier: umax = 30719 < 30720 */ - - if (current_size > 0) { - // args->buf is a user-space pointer; use bpf_probe_read_user so - // kernels >= 5.11 (where bpf_probe_read aliases _kernel) read it correctly. - if (bpf_probe_read_user(&socket_data_event->msg, current_size, - (const char *)args->buf + bytes_sent) != 0) { - break; - } - size_to_save = current_size; - } + if (current_size > MAX_MSG_SIZE) { + current_size = MAX_MSG_SIZE; + } - if (is_send) { - conn_info->writeEventsCount = (conn_info->writeEventsCount) + 1u; - } else { - conn_info->readEventsCount = (conn_info->readEventsCount) + 1u; - } + if (current_size_minus_1 < MAX_MSG_SIZE) { + bpf_probe_read(&socket_data_event->msg, current_size, args->buf + bytes_sent); + size_to_save = current_size; + } else if (current_size_minus_1 < 0x7fffffff) { + bpf_probe_read(&socket_data_event->msg, MAX_MSG_SIZE, args->buf + bytes_sent); + size_to_save = MAX_MSG_SIZE; + } - 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); - bpf_printk("current_size: %d i:%d, bytes_exchanged: %d", - current_size, i, bytes_exchanged); - bpf_printk("rwc: %d tdfd: %llu data: %s", - (socket_data_event->readEventsCount * 10000 + - socket_data_event->writeEventsCount % 10000), - tgid_fd, socket_data_event->msg); - } + if (is_send){ + conn_info->writeEventsCount = (conn_info->writeEventsCount) + 1u; + } else { + conn_info->readEventsCount = (conn_info->readEventsCount) + 1u; + } - socket_data_event->bytes_sent = is_send ? 1 : -1; - socket_data_event->bytes_sent *= size_to_save; - bpf_ringbuf_output(&socket_data_events, socket_data_event, - sizeof(struct socket_data_event_t) - MAX_MSG_SIZE + size_to_save, 0); + socket_data_event->writeEventsCount = conn_info->writeEventsCount; + socket_data_event->readEventsCount = conn_info->readEventsCount; + + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("pid: %d conn-id:%d, fd: %d", id, conn_info->id, conn_info->fd); + bpf_trace_printk("current_size: %d i:%d, bytes_exchanged: %d", current_size, i, bytes_exchanged); + unsigned long tdfd = ((id & 0xffff) << 32) + conn_info->fd; + bpf_trace_printk("rwc: %d tdfd: %llu data: %s", (socket_data_event->readEventsCount*10000 + socket_data_event->writeEventsCount%10000),tgid_fd, socket_data_event->msg); + } + + socket_data_event->bytes_sent = is_send ? 1 : -1; + socket_data_event->bytes_sent *= size_to_save; + socket_data_events.perf_submit(ret, socket_data_event, sizeof(struct socket_data_event_t) - MAX_MSG_SIZE + size_to_save); + + bytes_sent += current_size; + } - bytes_sent += current_size; - } } -static __always_inline void process_syscall_data_vecs(struct pt_regs* ctx, - struct data_args_t* args, - u64 id, bool is_send) { - int bytes_sent = 0; - int total_size = PT_REGS_RC(ctx); +static __inline void process_syscall_data_vecs(struct pt_regs* ret, struct data_args_t* args, u64 id, bool is_send){ + int bytes_sent=0; + int total_size = PT_REGS_RC(ret); const struct iovec* iov = args->iov; - for (int i = 0; i < LOOP_LIMIT && i < args->iovlen && bytes_sent < total_size; ++i) { + 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]); + bpf_probe_read(&iov_cpy, sizeof(iov_cpy), &iov[i]); const int bytes_remaining = total_size - bytes_sent; - const size_t iov_size = iov_cpy.iov_len < bytes_remaining - ? iov_cpy.iov_len : bytes_remaining; - - args->buf = iov_cpy.iov_base; + 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); + process_syscall_data(ret, args, id, is_send, false); bytes_sent += iov_size; - } + + } } -/* =================================================================== - * Kprobe hooks — syscall level - * All functions use SEC("kprobe"). The Go loader attaches them as - * kprobe or kretprobe based on the ProbeType in the hook tables. - * Syscall arguments are read from pt_regs via PT_REGS_PARM*_CORE_SYSCALL. - * =================================================================== */ - -SEC("kprobe") -int syscall__probe_entry_accept(struct pt_regs* ctx) { +// Hooks +int syscall__probe_entry_accept(struct pt_regs* ctx, int sockfd, struct sockaddr* addr, socklen_t* addrlen) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_accept: pid: %d", id); - } - - struct sockaddr* addr = (struct sockaddr*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_accept: pid: %d", id); + } struct accept_args_t accept_args = {}; accept_args.addr = addr; - bpf_map_update_elem(&active_accept_args_map, &id, &accept_args, BPF_ANY); - + active_accept_args_map.update(&id, &accept_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_accept(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_accept: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_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 = active_accept_args_map.lookup(&id); if (accept_args != NULL) { process_syscall_accept(ctx, accept_args, id, false); } - bpf_map_delete_elem(&active_accept_args_map, &id); + active_accept_args_map.delete(&id); return 0; } -SEC("kprobe") int probe_ret_sock_alloc(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - - if (print_bpf_logs) { - 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) { - return 0; - } + uint64_t id = bpf_get_current_pid_tgid(); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_ret_sock_alloc: pid: %d", id); + } + // Only trace sock_alloc() called by accept()/accept4(). + struct accept_args_t* accept_args = active_accept_args_map.lookup(&id); + if (accept_args == NULL) { + return 0; + } - 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); + } - return 0; + return 0; } -SEC("kprobe") int probe_entry_tcp_connect(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - - if (print_bpf_logs) { - 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) { - return 0; - } + uint64_t id = bpf_get_current_pid_tgid(); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tcp_connect: pid: %d", id); + } + // Only trace sock_alloc() called by accept()/accept4(). + struct accept_args_t* accept_args = active_accept_args_map.lookup(&id); + if (accept_args == NULL) { + return 0; + } - 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); + } - return 0; + return 0; } -SEC("kprobe") -int syscall__probe_entry_connect(struct pt_regs* ctx) { +int syscall__probe_entry_connect(struct pt_regs* ctx, int sockfd, struct sockaddr* addr, socklen_t* addrlen) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_connect: pid: %d", id); - } - - int sockfd = (int)SYSCALL_PARM1(ctx); - struct sockaddr* addr = (struct sockaddr*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_connect: pid: %d", id); + } struct accept_args_t accept_args = {}; - accept_args.fd = sockfd; + accept_args.fd = sockfd; accept_args.addr = addr; - bpf_map_update_elem(&active_accept_args_map, &id, &accept_args, BPF_ANY); - + active_accept_args_map.update(&id, &accept_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_connect(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_connect: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_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 = active_accept_args_map.lookup(&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); - } - process_syscall_accept(ctx, accept_args, id, true); + if (accept_args->sock != NULL) { + struct sock *sock = accept_args->sock; + struct socket *s; + bpf_probe_read_kernel(&(s), sizeof(s), &sock->sk_socket); + accept_args->sock_alloc_socket = s; + } + process_syscall_accept(ctx, accept_args, id, true); } - bpf_map_delete_elem(&active_accept_args_map, &id); + active_accept_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_close(struct pt_regs* ctx) { +int syscall__probe_entry_close(struct pt_regs* ctx, int fd) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_close: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_close: pid: %d", id); + } struct close_args_t close_args = {}; close_args.fd = fd; - bpf_map_update_elem(&active_close_args_map, &id, &close_args, BPF_ANY); - + active_close_args_map.update(&id, &close_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_close(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_close: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_close: pid: %d", id); + } - struct close_args_t* close_args = bpf_map_lookup_elem(&active_close_args_map, &id); + struct close_args_t* close_args = active_close_args_map.lookup(&id); if (close_args != NULL) { process_syscall_close(ctx, close_args, id); } - bpf_map_delete_elem(&active_close_args_map, &id); + active_close_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_writev(struct pt_regs* ctx) { +int syscall__probe_entry_writev(struct pt_regs* ctx, int fd, const struct iovec* iov, int iovlen){ u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_writev: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); - const struct iovec* iov = (const struct iovec*)SYSCALL_PARM2(ctx); - int iovlen = (int)SYSCALL_PARM3(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_writev: pid: %d", id); + } struct data_args_t write_args = {}; - write_args.fd = fd; - write_args.iov = iov; + write_args.fd = fd; + write_args.iov = iov; write_args.iovlen = iovlen; write_args.source_fn = kSyscallWriteV; - struct data_args_t* existing = bpf_map_lookup_elem(&active_write_args_map, &id); - if (existing != NULL && existing->sock_event) { - write_args.sock_event = true; + struct data_args_t* existing_write_args = active_write_args_map.lookup(&id); + if (existing_write_args != NULL && existing_write_args->sock_event) { + write_args.sock_event = true; } - bpf_map_update_elem(&active_write_args_map, &id, &write_args, BPF_ANY); - + active_write_args_map.update(&id, &write_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_writev(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_writev: pid: %d", id); + } - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_writev: pid: %d", id); - } - - 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. */ + struct data_args_t* write_args = active_write_args_map.lookup(&id); if (write_args != NULL && write_args->sock_event) { - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_writev data process: pid: %d", id); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_writev data process: pid: %d", id); } - process_syscall_data_vecs(ctx, write_args, id, true); + process_syscall_data_vecs(ctx, write_args, id, true); } - - bpf_map_delete_elem(&active_write_args_map, &id); + + active_write_args_map.delete(&id); return 0; -} + } -SEC("kprobe") -int syscall__probe_entry_sendmsg(struct pt_regs* ctx) { +int syscall__probe_entry_sendmsg(struct pt_regs* ctx, int fd, struct user_msghdr* msghdr){ u64 id = bpf_get_current_pid_tgid(); - int fd = (int)SYSCALL_PARM1(ctx); - struct user_msghdr* msghdr = (struct user_msghdr*)SYSCALL_PARM2(ctx); - - if (msghdr != NULL) { - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_sendmsg: pid: %d", id); - } - - struct user_msghdr msghdr_copy = {}; - if (bpf_probe_read_user(&msghdr_copy, sizeof(msghdr_copy), msghdr) != 0) { - return 0; - } - - struct data_args_t write_args = {}; - write_args.fd = fd; - write_args.iov = msghdr_copy.msg_iov; - write_args.iovlen = msghdr_copy.msg_iovlen; + if (msghdr != NULL) { + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_sendmsg: pid: %d", id); + } + + struct data_args_t write_args = {}; + write_args.fd = fd; + write_args.iov = msghdr->msg_iov; + write_args.iovlen = msghdr->msg_iovlen; write_args.source_fn = kSyscallSendMsg; - bpf_map_update_elem(&active_write_args_map, &id, &write_args, BPF_ANY); - } - + active_write_args_map.update(&id, &write_args); + } + return 0; } -SEC("kprobe") int syscall__probe_ret_sendmsg(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_sendmsg: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_sendmsg: pid: %d", id); + } - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); + struct data_args_t* write_args = active_write_args_map.lookup(&id); if (write_args != NULL) { - process_syscall_data_vecs(ctx, write_args, id, true); + process_syscall_data_vecs(ctx, write_args, id, true); } - - bpf_map_delete_elem(&active_write_args_map, &id); + + active_write_args_map.delete(&id); return 0; -} + } -SEC("kprobe") -int syscall__probe_entry_readv(struct pt_regs* ctx) { + int syscall__probe_entry_readv(struct pt_regs* ctx, int fd, struct iovec* iov, int iovlen) { u64 id = bpf_get_current_pid_tgid(); - - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_readv: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); - struct iovec* iov = (struct iovec*)SYSCALL_PARM2(ctx); - int iovlen = (int)SYSCALL_PARM3(ctx); - + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_readv: pid: %d", id); + } + struct data_args_t read_args = {}; - read_args.fd = fd; - read_args.iov = iov; - read_args.iovlen = iovlen; + read_args.fd = fd; + read_args.iov = iov; + read_args.iovlen = iovlen; read_args.source_fn = kSyscallReadV; - struct data_args_t* existing = bpf_map_lookup_elem(&active_read_args_map, &id); - if (existing != NULL && existing->sock_event) { - read_args.sock_event = true; + struct data_args_t* existing_read_args = active_read_args_map.lookup(&id); + if (existing_read_args != NULL && existing_read_args->sock_event) { + read_args.sock_event = true; } - bpf_map_update_elem(&active_read_args_map, &id, &read_args, BPF_ANY); - + active_read_args_map.update(&id, &read_args); + return 0; -} - -SEC("kprobe") -int syscall__probe_ret_readv(struct pt_regs* ctx) { + } + + int syscall__probe_ret_readv(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_readv: pid: %d", id); - } - - 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(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_readv: pid: %d", id); + } + + struct data_args_t* read_args = active_read_args_map.lookup(&id); if (read_args != NULL && read_args->sock_event) { - process_syscall_data_vecs(ctx, read_args, id, false); + process_syscall_data_vecs(ctx, read_args, id, false); } - - bpf_map_delete_elem(&active_read_args_map, &id); + + active_read_args_map.delete(&id); return 0; -} + } -SEC("kprobe") -int syscall__probe_entry_recvfrom(struct pt_regs* ctx) { +int syscall__probe_entry_recvfrom(struct pt_regs* ctx, int fd, char* buf, size_t count, + int flags, struct sockaddr* src_addr, socklen_t* addrlen) { u64 id = bpf_get_current_pid_tgid(); - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + struct data_args_t* read_args_1 = active_read_args_map.lookup(&id); - if (print_bpf_logs) { - struct data_args_t* read_args_1 = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args_1 != NULL) { - bpf_printk("syscall__probe_entry_recvfrom: pid: %llu fd: %d read args : %d", - id, fd, read_args_1->fd); - } else { - bpf_printk("syscall__probe_entry_recvfrom: pid: %llu fd: %d read args : NULL", - id, fd); - } + if (read_args_1 != NULL){ + bpf_trace_printk("syscall__probe_entry_recvfrom: pid: %llu fd: %d read args : %d", id, fd, read_args_1->fd); + } else { + bpf_trace_printk("syscall__probe_entry_recvfrom: pid: %llu fd: %d read args : NULL", id, fd); } + } struct data_args_t read_args = {}; - read_args.buf = buf; - read_args.fd = fd; - read_args.source_fn = kSyscallRecvFrom; - bpf_map_update_elem(&active_read_args_map, &id, &read_args, BPF_ANY); - + read_args.buf = buf; + read_args.fd = fd; + read_args.source_fn = kSyscallRecvFrom; + active_read_args_map.update(&id, &read_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_recvfrom(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_recvfrom: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_recvfrom: pid: %d", id); + } - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); + struct data_args_t* read_args = active_read_args_map.lookup(&id); if (read_args != NULL) { process_syscall_data(ctx, read_args, id, false, false); } - bpf_map_delete_elem(&active_read_args_map, &id); + active_read_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_sendto(struct pt_regs* ctx) { +int syscall__probe_entry_sendto(struct pt_regs* ctx, int fd, char* buf, size_t count, + int flags, const struct sockaddr* dest_addr, socklen_t addrlen) { u64 id = bpf_get_current_pid_tgid(); - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + struct data_args_t* write_args_1 = active_write_args_map.lookup(&id); - if (print_bpf_logs) { - struct data_args_t* write_args_1 = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args_1 != NULL) { - bpf_printk("syscall__probe_entry_sendto: pid: %llu fd: %d write args : %d", - id, fd, write_args_1->fd); - } else { - bpf_printk("syscall__probe_entry_sendto: pid: %llu fd: %d write args : NULL", - id, fd); - } + if (write_args_1 != NULL) { + bpf_trace_printk("syscall__probe_entry_sendto: pid: %llu fd: %d write args : %d", id, fd, write_args_1->fd); + } else { + bpf_trace_printk("syscall__probe_entry_sendto: pid: %llu fd: %d write args : NULL", id, fd); } + } struct data_args_t write_args = {}; - write_args.buf = buf; - write_args.fd = fd; - write_args.source_fn = kSyscallSendTo; - bpf_map_update_elem(&active_write_args_map, &id, &write_args, BPF_ANY); - + write_args.buf = buf; + write_args.fd = fd; + write_args.source_fn = kSyscallSendTo; + active_write_args_map.update(&id, &write_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_sendto(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_sendto: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_sendto: pid: %d", id); + } - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); + struct data_args_t* write_args = active_write_args_map.lookup(&id); if (write_args != NULL) { process_syscall_data(ctx, write_args, id, true, false); } - bpf_map_delete_elem(&active_write_args_map, &id); + active_write_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_recv(struct pt_regs* ctx) { +int syscall__probe_entry_recv(struct pt_regs* ctx, int fd, char* buf, size_t count) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_recv: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_recv: pid: %d", id); + } struct data_args_t read_args = {}; - read_args.buf = buf; - read_args.fd = fd; - read_args.source_fn = kSyscallRecv; - bpf_map_update_elem(&active_read_args_map, &id, &read_args, BPF_ANY); - + read_args.buf = buf; + read_args.fd = fd; + read_args.source_fn = kSyscallRecv; + active_read_args_map.update(&id, &read_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_recv(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_recv: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_recv: pid: %d", id); + } - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); + struct data_args_t* read_args = active_read_args_map.lookup(&id); if (read_args != NULL) { process_syscall_data(ctx, read_args, id, false, false); } - bpf_map_delete_elem(&active_read_args_map, &id); + active_read_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_read(struct pt_regs* ctx) { +int syscall__probe_entry_read(struct pt_regs* ctx, int fd, char* buf, size_t count) { u64 id = bpf_get_current_pid_tgid(); - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + struct data_args_t* read_args_1 = active_read_args_map.lookup(&id); - if (print_bpf_logs) { - struct data_args_t* read_args_1 = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args_1 != NULL) { - bpf_printk("syscall__probe_entry_read: pid: %llu fd: %d read args : %d", - id, fd, read_args_1->fd); - } else { - bpf_printk("syscall__probe_entry_read: pid: %llu fd: %d read args : NULL", - id, fd); - } + if (read_args_1 != NULL) + { + bpf_trace_printk("syscall__probe_entry_read: pid: %llu fd: %d read args : %d", id, fd, read_args_1->fd); } + else + { + bpf_trace_printk("syscall__probe_entry_read: pid: %llu fd: %d read args : NULL", id, fd); + } + } struct data_args_t read_args = {}; - read_args.buf = buf; - read_args.fd = fd; - read_args.source_fn = kSyscallRead; + read_args.buf = buf; + read_args.fd = fd; + read_args.source_fn = kSyscallRead; - struct data_args_t* existing = bpf_map_lookup_elem(&active_read_args_map, &id); - if (existing != NULL && existing->sock_event) { - read_args.sock_event = true; + struct data_args_t* existing_read_args = active_read_args_map.lookup(&id); + if (existing_read_args != NULL && existing_read_args->sock_event) { + read_args.sock_event = true; } - bpf_map_update_elem(&active_read_args_map, &id, &read_args, BPF_ANY); - + active_read_args_map.update(&id, &read_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_read(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_read: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_read: pid: %d", id); + } - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); + struct data_args_t* read_args = active_read_args_map.lookup(&id); - /* 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); } - bpf_map_delete_elem(&active_read_args_map, &id); + active_read_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_recvmsg(struct pt_regs* ctx) { +int syscall__probe_entry_recvmsg(struct pt_regs* ctx, int fd, struct user_msghdr* msghdr) { u64 id = bpf_get_current_pid_tgid(); - int fd = (int)SYSCALL_PARM1(ctx); - struct user_msghdr* msghdr = (struct user_msghdr*)SYSCALL_PARM2(ctx); - - if (msghdr != NULL) { - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_recvmsg: pid: %d", id); - } - - struct user_msghdr msghdr_copy = {}; - if (bpf_probe_read_user(&msghdr_copy, sizeof(msghdr_copy), msghdr) != 0) { - return 0; - } - - struct data_args_t read_args = {}; - read_args.fd = fd; - read_args.iov = msghdr_copy.msg_iov; - read_args.iovlen = msghdr_copy.msg_iovlen; - read_args.source_fn = kSyscallRecvMsg; - bpf_map_update_elem(&active_read_args_map, &id, &read_args, BPF_ANY); - } - + if (msghdr != NULL) { + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_recvmsg: pid: %d", id); + } + + struct data_args_t read_args = {}; + read_args.fd = fd; + read_args.iov = msghdr->msg_iov; + read_args.iovlen = msghdr->msg_iovlen; + read_args.source_fn = kSyscallRecvMsg; + active_read_args_map.update(&id, &read_args); + } + return 0; } -SEC("kprobe") int syscall__probe_ret_recvmsg(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_recvmsg: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_recvmsg: pid: %d", id); + } - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); + struct data_args_t* read_args = active_read_args_map.lookup(&id); if (read_args != NULL) { process_syscall_data_vecs(ctx, read_args, id, false); } - bpf_map_delete_elem(&active_read_args_map, &id); + active_read_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_send(struct pt_regs* ctx) { +int syscall__probe_entry_send(struct pt_regs* ctx, int fd, char* buf, size_t count) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_send: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_send: pid: %d", id); + } struct data_args_t write_args = {}; - write_args.buf = buf; - write_args.fd = fd; - write_args.source_fn = kSyscallSend; - bpf_map_update_elem(&active_write_args_map, &id, &write_args, BPF_ANY); - + write_args.buf = buf; + write_args.fd = fd; + write_args.source_fn = kSyscallSend; + active_write_args_map.update(&id, &write_args); + return 0; } -SEC("kprobe") int syscall__probe_ret_send(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_ret_send: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_send: pid: %d", id); + } - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); + struct data_args_t* write_args = active_write_args_map.lookup(&id); if (write_args != NULL) { process_syscall_data(ctx, write_args, id, true, false); } - bpf_map_delete_elem(&active_write_args_map, &id); + active_write_args_map.delete(&id); return 0; } -SEC("kprobe") -int syscall__probe_entry_write(struct pt_regs* ctx) { +int syscall__probe_entry_write(struct pt_regs* ctx, int fd, char* buf, size_t count) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("syscall__probe_entry_write: pid: %d", id); - } - - int fd = (int)SYSCALL_PARM1(ctx); - char* buf = (char*)SYSCALL_PARM2(ctx); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_entry_write: pid: %d", id); + } struct data_args_t write_args = {}; - write_args.buf = buf; - write_args.fd = fd; - write_args.source_fn = kSyscallWrite; + write_args.buf = buf; + write_args.fd = fd; + write_args.source_fn = kSyscallWrite; - struct data_args_t* existing = bpf_map_lookup_elem(&active_write_args_map, &id); - if (existing != NULL && existing->sock_event) { - write_args.sock_event = true; + struct data_args_t* existing_write_args = active_write_args_map.lookup(&id); + if (existing_write_args != NULL && existing_write_args->sock_event) { + write_args.sock_event = true; } - - bpf_map_update_elem(&active_write_args_map, &id, &write_args, BPF_ANY); + + active_write_args_map.update(&id, &write_args); return 0; } -SEC("kprobe") int syscall__probe_ret_write(struct pt_regs* ctx) { u64 id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - struct data_args_t* write_args_1 = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args_1 != NULL) { - bpf_printk("syscall__probe_ret_write: pid: %llu write args : %d", - id, write_args_1->fd); - } else { - bpf_printk("syscall__probe_ret_write: pid: %llu write args : NULL", id); - } + if(PRINT_BPF_LOGS){ + struct data_args_t* write_args_1 = active_write_args_map.lookup(&id); + + if (write_args_1 != NULL) { + bpf_trace_printk("syscall__probe_ret_write: pid: %llu write args : %d", id, write_args_1->fd); + } else { + bpf_trace_printk("syscall__probe_ret_write: pid: %llu write args : NULL", id); } + } - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); + struct data_args_t* write_args = active_write_args_map.lookup(&id); - /* 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); - } - process_syscall_data(ctx, write_args, id, true, false); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("syscall__probe_ret_write data process: pid: %d", id); + } + + process_syscall_data(ctx, write_args, id, true, false); } - bpf_map_delete_elem(&active_write_args_map, &id); + active_write_args_map.delete(&id); return 0; } -SEC("kprobe") -int probe_entry_security_socket_sendmsg(struct pt_regs* ctx) { - u64 id = bpf_get_current_pid_tgid(); +struct node_tlswrap_symaddrs_t { + u32 TLSWrapStreamListenerOffset; + u32 StreamListenerStreamOffset; + u32 StreamBaseStreamResourceOffset; + u32 LibuvStreamWrapStreamBaseOffset; + u32 LibuvStreamWrapStreamOffset; + u32 UVStreamSIOWatcherOffset; + u32 UVIOSFDOffset; +}; - if (print_bpf_logs) { - bpf_printk("probe_entry_security_socket_sendmsg: pid: %d", id); - } - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args != NULL) { - write_args->sock_event = true; - } +BPF_HASH(node_tlswrap_symaddrs_map, u32, struct node_tlswrap_symaddrs_t); +BPF_HASH(active_TLSWrap_memfn_this, uint64_t, void*); +BPF_HASH(node_ssl_tls_wrap_map, void*, void*); + +static __inline int32_t get_fd_from_tlswrap_ptr(const struct node_tlswrap_symaddrs_t* symaddrs, + void* tlswrap) { + void* stream_ptr = + tlswrap + symaddrs->TLSWrapStreamListenerOffset + symaddrs->StreamListenerStreamOffset; + void* stream = NULL; + + bpf_probe_read(&stream, sizeof(stream), stream_ptr); + + if (stream == NULL) { return 0; -} + } -SEC("kprobe") -int probe_entry_security_socket_recvmsg(struct pt_regs* ctx) { - u64 id = bpf_get_current_pid_tgid(); + void* uv_stream_ptr = stream - symaddrs->StreamBaseStreamResourceOffset - + symaddrs->LibuvStreamWrapStreamBaseOffset + + symaddrs->LibuvStreamWrapStreamOffset; - if (print_bpf_logs) { - bpf_printk("probe_entry_security_socket_recvmsg: pid: %d", id); - } + void* uv_stream = NULL; + bpf_probe_read(&uv_stream, sizeof(uv_stream), uv_stream_ptr); - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { - read_args->sock_event = true; - } + if (uv_stream == NULL) { return 0; -} + } -SEC("kprobe") -int probe_entry_setsockopt(struct pt_regs* ctx) { - u64 id = bpf_get_current_pid_tgid(); + int32_t* fd_ptr = + uv_stream + symaddrs->UVStreamSIOWatcherOffset + symaddrs->UVIOSFDOffset; - if (print_bpf_logs) { - bpf_printk("probe_entry_setsockopt: pid: %d", id); - } + int32_t fd = 0; - struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args != NULL) { - write_args->sock_event = true; - } - struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { - read_args->sock_event = true; - } + if (bpf_probe_read(&fd, sizeof(fd), fd_ptr) != 0) { return 0; + } + + return fd; } -/* =================================================================== - * SSL / OpenSSL uprobe helpers and probes - * BPF_UPROBE extracts named args from pt_regs; ctx is still available. - * =================================================================== */ +static __inline int32_t get_fd_node(uint32_t tgid, void* ssl) { + void** tls_wrap_ptr = node_ssl_tls_wrap_map.lookup(&ssl); + if (tls_wrap_ptr == NULL) { + return 0; + } + + const struct node_tlswrap_symaddrs_t* symaddrs = node_tlswrap_symaddrs_map.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } + + return get_fd_from_tlswrap_ptr(symaddrs, *tls_wrap_ptr); +} -static u32 get_fd(void* ssl, int sslVersion, bool rw) { +static u32 get_fd(void *ssl, int sslVersion, bool rw) { int32_t SSL_rbio_offset; - int32_t RBIO_num_offset = 0; + int32_t RBIO_num_offset; - SSL_rbio_offset = 16; - switch (sslVersion) { - case 1: + SSL_rbio_offset = 16; + switch (sslVersion) + { + case 1: RBIO_num_offset = 40; - break; - case 2: + break; + case 2: RBIO_num_offset = 48; - break; - case 3: + break; + case 3: RBIO_num_offset = 56; - break; - case 4: + break; + case 4: SSL_rbio_offset = 24; RBIO_num_offset = 24; - break; + break; default: - break; + break; } - const void* rbio_ptr; - bpf_probe_read_user(&rbio_ptr, sizeof(rbio_ptr), ssl + SSL_rbio_offset); - u32 rbio_num; - bpf_probe_read_user(&rbio_num, sizeof(rbio_num), rbio_ptr + RBIO_num_offset); - - if (print_bpf_logs) { - bpf_printk("SSL fd offset: %d %d %d", rbio_num, - SSL_rbio_offset, RBIO_num_offset); + const void** rbio_ptr_addr = ssl + SSL_rbio_offset; + const void* rbio_ptr = *rbio_ptr_addr; + const int* rbio_num_addr = rbio_ptr + RBIO_num_offset; + u32 rbio_num = *rbio_num_addr; + if(PRINT_BPF_LOGS){ + bpf_trace_printk("SSL fd offset: %d %d %d", rbio_num, SSL_rbio_offset, RBIO_num_offset); } return rbio_num; } -static void set_conn_as_ssl(u32 tgid, u32 fd) { +static void set_conn_as_ssl(u32 tgid, u32 fd){ u64 tgid_fd = gen_tgid_fd(tgid, fd); - if (print_bpf_logs) { - bpf_printk("SSL tgid: %d", tgid_fd); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("SSL tgid: %d", tgid_fd); } - struct conn_info_t* conn_info = bpf_map_lookup_elem(&conn_info_map, &tgid_fd); + struct conn_info_t* conn_info = conn_info_map.lookup(&tgid_fd); if (conn_info == NULL) { return; } - if (print_bpf_logs) { - bpf_printk("SSL marking ssl tgid: %d", tgid_fd); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("SSL marking ssl tgid: %d", tgid_fd); } conn_info->ssl = true; } -/* - * probe_entry_SSL_write_core — shared inner handler for all SSL write entry probes. - * With BPF_UPROBE, buf is already extracted from pt_regs by the macro; we pass it directly. - */ -static void probe_entry_SSL_write_core(struct pt_regs* ctx, void* ssl, void* buf, - int num, u32 fd) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; +static void probe_entry_SSL_write_core(struct pt_regs *ctx, void *ssl, void *buf, int num, u32 fd){ + u64 id = bpf_get_current_pid_tgid(); + u32 tgid = id >> 32; - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write_core: pid: %d %d %d", id, tgid, fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write_core: pid: %d %d %d", id, tgid, fd); + } - char* bufc = (char*)buf; + char* bufc = (char*)PT_REGS_PARM2(ctx); - struct data_args_t write_args = {}; - write_args.fd = fd; - write_args.buf = bufc; - bpf_map_update_elem(&active_ssl_write_args_map, &id, &write_args, BPF_ANY); + struct data_args_t write_args = {}; + write_args.fd = fd; + write_args.buf = bufc; + active_ssl_write_args_map.update(&id, &write_args); - set_conn_as_ssl(tgid, write_args.fd); + // Mark connection as SSL right away, so encrypted traffic does not get traced. + set_conn_as_ssl(tgid, write_args.fd); } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_write_1_0, void* ssl, void* buf, int num) { +int probe_entry_SSL_write_1_0(struct pt_regs *ctx, void *ssl, void *buf, int num) { u32 fd = get_fd(ssl, 1, false); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write_1_0: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write_1_0: fd: %d", fd); + } probe_entry_SSL_write_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_write_1_1, void* ssl, void* buf, int num) { +int probe_entry_SSL_write_1_1(struct pt_regs *ctx, void *ssl, void *buf, int num) { u32 fd = get_fd(ssl, 2, false); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write_1_1: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write_1_1: fd: %d", fd); + } probe_entry_SSL_write_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_write_3_0, void* ssl, void* buf, int num) { +int probe_entry_SSL_write_3_0(struct pt_regs *ctx, void *ssl, void *buf, int num) { u32 fd = get_fd(ssl, 3, false); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write_3_0: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write_3_0: fd: %d", fd); + } probe_entry_SSL_write_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -/* Node-OpenSSL only: FD resolved via the TLS-wrap map. */ -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_write, void* ssl, void* buf, int num) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; - - __u64 ssl_key = (__u64)ssl; - __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 */ - u32 tgid_key = tgid; - struct node_tlswrap_symaddrs_t* symaddrs = - 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; - 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; - 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_val = 0; - if (bpf_probe_read(&fd_val, sizeof(fd_val), fd_ptr) == 0) { - fd = (u32)fd_val; - } - } - } - } - } - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write: fd: %d", fd); - } +// using this probe for node-openSSL only. +int probe_entry_SSL_write(struct pt_regs *ctx, void *ssl, void *buf, int num) { + u64 id = bpf_get_current_pid_tgid(); + u32 tgid = id >> 32; + u32 fd = get_fd_node(tgid, ssl); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write: fd: %d", fd); + } probe_entry_SSL_write_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_write_boring, void* ssl, void* buf, int num) { +int probe_entry_SSL_write_boring(struct pt_regs *ctx, void *ssl, void *buf, int num) { u32 fd = get_fd(ssl, 4, false); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_write_boring: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_write_boring: fd: %d", fd); + } probe_entry_SSL_write_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") int probe_ret_SSL_write(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); + uint64_t id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("probe_ret_SSL_write: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_ret_SSL_write: pid: %d", id); + } - const struct data_args_t* write_args = bpf_map_lookup_elem(&active_ssl_write_args_map, &id); - if (write_args != NULL) { - process_syscall_data(ctx, write_args, id, true, true); - } + const struct data_args_t* write_args = active_ssl_write_args_map.lookup(&id); + if (write_args != NULL) { + process_syscall_data(ctx, write_args, id, true, true); + } - bpf_map_delete_elem(&active_ssl_write_args_map, &id); - return 0; + active_ssl_write_args_map.delete(&id); + return 0; } -static void probe_entry_SSL_read_core(struct pt_regs* ctx, void* ssl, void* buf, - int num, u32 fd) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; +static void probe_entry_SSL_read_core(struct pt_regs *ctx, void *ssl, void *buf, int num, u32 fd){ + u64 id = bpf_get_current_pid_tgid(); + u32 tgid = id >> 32; - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read_core: pid: %d %d %d", id, tgid, fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read_core: pid: %d %d %d", id, tgid, fd); + } - char* bufc = (char*)buf; + char* bufc = (char*)PT_REGS_PARM2(ctx); - struct data_args_t read_args = {}; - read_args.fd = fd; - read_args.buf = bufc; - bpf_map_update_elem(&active_ssl_read_args_map, &id, &read_args, BPF_ANY); + struct data_args_t read_args = {}; + read_args.fd = fd; + read_args.buf = bufc; + active_ssl_read_args_map.update(&id, &read_args); - set_conn_as_ssl(tgid, read_args.fd); + // Mark connection as SSL right away, so encrypted traffic does not get traced. + set_conn_as_ssl(tgid, read_args.fd); } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_read_1_0, void* ssl, void* buf, int num) { +int probe_entry_SSL_read_1_0(struct pt_regs *ctx, void *ssl, void *buf, int num) { int32_t fd = get_fd(ssl, 1, true); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read_1_0: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read_1_0: fd: %d", fd); + } probe_entry_SSL_read_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_read_1_1, void* ssl, void* buf, int num) { +int probe_entry_SSL_read_1_1(struct pt_regs *ctx, void *ssl, void *buf, int num) { int32_t fd = get_fd(ssl, 2, true); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read_1_1: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read_1_1: fd: %d", fd); + } probe_entry_SSL_read_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_read_3_0, void* ssl, void* buf, int num) { +int probe_entry_SSL_read_3_0(struct pt_regs *ctx, void *ssl, void *buf, int num) { int32_t fd = get_fd(ssl, 3, true); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read_3_0: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read_3_0: fd: %d", fd); + } probe_entry_SSL_read_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -/* Node-OpenSSL only. */ -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_read, void* ssl, void* buf, int num) { - u64 id = bpf_get_current_pid_tgid(); - u32 tgid = id >> 32; - - __u64 ssl_key = (__u64)ssl; - __u64* tls_wrap_val = bpf_map_lookup_elem(&node_ssl_tls_wrap_map, &ssl_key); - int32_t fd = 0; - if (tls_wrap_val != NULL) { - u32 tgid_key = tgid; - struct node_tlswrap_symaddrs_t* symaddrs = - 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; - 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; - 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_val = 0; - if (bpf_probe_read(&fd_val, sizeof(fd_val), fd_ptr) == 0) { - fd = fd_val; - } - } - } - } - } - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read: fd: %d", fd); - } +// using this probe for node-openSSL only. +int probe_entry_SSL_read(struct pt_regs *ctx, void *ssl, void *buf, int num) { + u64 id = bpf_get_current_pid_tgid(); + u32 tgid = id >> 32; + int32_t fd = get_fd_node(tgid, ssl); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read: fd: %d", fd); + } probe_entry_SSL_read_core(ctx, ssl, buf, num, fd); - return 0; + return 0; } -SEC("uprobe") -int BPF_UPROBE(probe_entry_SSL_read_boring, void* ssl, void* buf, int num) { +int probe_entry_SSL_read_boring(struct pt_regs *ctx, void *ssl, void *buf, int num) { int32_t fd = get_fd(ssl, 4, true); - if (print_bpf_logs) { - bpf_printk("probe_entry_SSL_read_boring: fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_SSL_read_boring: fd: %d", fd); + } probe_entry_SSL_read_core(ctx, ssl, buf, num, fd); - return 0; + + return 0; } -SEC("uprobe") int probe_ret_SSL_read(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); + uint64_t id = bpf_get_current_pid_tgid(); - if (print_bpf_logs) { - bpf_printk("probe_ret_SSL_read: pid: %d", id); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_ret_SSL_read: pid: %d", id); + } - const struct data_args_t* read_args = bpf_map_lookup_elem(&active_ssl_read_args_map, &id); - if (read_args != NULL) { - process_syscall_data(ctx, read_args, id, false, true); - } + const struct data_args_t* read_args = active_ssl_read_args_map.lookup(&id); + if (read_args != NULL) { + process_syscall_data(ctx, read_args, id, false, true); + } - bpf_map_delete_elem(&active_ssl_read_args_map, &id); - return 0; + active_ssl_read_args_map.delete(&id); + return 0; } -/* =================================================================== - * Go TLS probes - * =================================================================== */ +// Trace kernel function: +// int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) +// which is called by write/writev +int probe_entry_security_socket_sendmsg(struct pt_regs* ctx) { + u64 id = bpf_get_current_pid_tgid(); -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; - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_security_socket_sendmsg: pid: %d", id); + } + struct data_args_t* write_args = active_write_args_map.lookup(&id); + if (write_args != NULL) { + write_args->sock_event = true; + } + return 0; +} + +// Trace kernel function: +// int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, int size) +int probe_entry_security_socket_recvmsg(struct pt_regs* ctx) { + u64 id = bpf_get_current_pid_tgid(); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_security_socket_recvmsg: pid: %d", id); + } + + struct data_args_t* read_args = active_read_args_map.lookup(&id); + if (read_args != NULL) { + read_args->sock_event = true; + } + return 0; +} + +int probe_entry_setsockopt(struct pt_regs* ctx, int socket, int level, int option_name, + const void *option_value, socklen_t option_len) { + u64 id = bpf_get_current_pid_tgid(); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_setsockopt: pid: %d", id); + } + + struct data_args_t* write_args = active_write_args_map.lookup(&id); + if (write_args != NULL) { + write_args->sock_event = true; + } + struct data_args_t* read_args = active_read_args_map.lookup(&id); + if (read_args != NULL) { + read_args->sock_event = true; + } + return 0; +} + +struct tgid_goid_t { + u32 tgid; + long long goid; +}; + +struct go_tls_conn_args { + void* conn_ptr; + char* plaintext_ptr; +}; + +struct go_interface { + int64_t type; + void* ptr; +}; + +enum location_type_t { + kLocationTypeStack = 1, + kLocationTypeRegisters = 2 +}; +struct location_t{ + enum location_type_t type; + u32 offset; +}; + +struct go_symaddrs_t { + u64 FDSysFDOffset; + u64 TLSConnOffset; + u64 GIDOffset; + u64 TCPConnOffset; + u64 IsClientOffset; + + struct location_t WriteConnectionLoc; + struct location_t WriteBufferLoc; + struct location_t WriteRet0Loc; + struct location_t WriteRet1Loc; + + struct location_t ReadConnectionLoc; + struct location_t ReadBufferLoc; + struct location_t ReadRet0Loc; + struct location_t ReadRet1Loc; + +}; + +struct go_regabi_regs { + uint64_t regs[9]; +}; + +BPF_PERCPU_ARRAY(regs_heap, struct go_regabi_regs, 1); + +static __inline uint64_t* go_regabi_regs(const struct pt_regs* ctx) { + uint32_t kZero = 0; + struct go_regabi_regs* regs_heap_var = regs_heap.lookup(&kZero); + if (regs_heap_var == NULL) { + return NULL; + } #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_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; #elif defined(TARGET_ARCH_AARCH64) #pragma unroll - for (uint32_t i = 0; i < 9; i++) { - regs_heap_var->regs[i] = ctx->regs[i]; - } + for (uint32_t i = 0; i < 9; i++) { + regs_heap_var->regs[i] = ctx->regs[i]; + } #else #error Target Architecture not supported #endif - return regs_heap_var->regs; + return regs_heap_var->regs; } +BPF_HASH(go_symaddrs_table, u32, struct go_symaddrs_t); +BPF_HASH(active_tls_conn_op_map, struct tgid_goid_t, struct go_tls_conn_args); + 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) { - return 0; - } + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; + struct go_symaddrs_t* common_symaddrs = go_symaddrs_table.lookup(&tgid); + if (common_symaddrs == NULL) { + return 0; + } - /* CO-RE: resolve task_struct->thread field offsets from BTF. */ - struct task_struct* task_ptr = (struct task_struct*)bpf_get_current_task(); - if (!task_ptr) { - return 0; - } + // Get fsbase from `struct task_struct`. + const struct task_struct* task_ptr = (struct task_struct*)bpf_get_current_task(); + if (!task_ptr) { + return 0; + } #if defined(TARGET_ARCH_X86_64) - const void* fs_base = (void*)BPF_CORE_READ(task_ptr, thread.fsbase); + const void* fs_base = (void*)task_ptr->thread.fsbase; #elif defined(TARGET_ARCH_AARCH64) - const void* fs_base = (void*)BPF_CORE_READ(task_ptr, thread.uw.tp_value); + const void* fs_base = (void*)task_ptr->thread.uw.tp_value; #else #error Target architecture not supported #endif - int32_t g_addr_offset = -8; - uint64_t goid; - 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)); - return goid; -} - -static __always_inline void assign_arg(void* arg, size_t arg_size, struct location_t loc, - const void* sp, uint64_t* regs) { - if (loc.type == kLocationTypeStack) { - bpf_probe_read_user(arg, arg_size, sp + loc.offset); - } else if (loc.type == kLocationTypeRegisters) { - if (loc.offset >= 0) { - bpf_probe_read(arg, arg_size, (char*)regs + loc.offset); - } - } + // Get ptr to `struct g` from 8 bytes before fsbase and then access the goID. + int32_t g_addr_offset = -8; + uint64_t goid; + 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)); + return goid; } -static __always_inline int32_t get_fd_from_conn_intf_core(struct go_interface conn_intf, - const struct go_symaddrs_t* symaddrs) { - // All pointers here live in the Go process heap (user space). - // On kernels >= 5.11 bpf_probe_read() aliases bpf_probe_read_kernel() - // and returns -EFAULT for user-space addresses. Use bpf_probe_read_user(). - // - // Also skip the TCPConnOffset type check: that value comes from DWARF and - // does not match the runtime interface type pointer for PIE binaries. - if (bpf_probe_read_user(&conn_intf, sizeof(conn_intf), - conn_intf.ptr + symaddrs->TLSConnOffset) != 0) { - return 0; - } - if (conn_intf.ptr == NULL) { - return 0; +static __inline void assign_arg(void* arg, size_t arg_size, struct location_t loc, const void* sp, + uint64_t* regs) { + if (loc.type == kLocationTypeStack) { + bpf_probe_read(arg, arg_size, sp + loc.offset); + } else if (loc.type == kLocationTypeRegisters) { + if (loc.offset >= 0) { + bpf_probe_read(arg, arg_size, (char*)regs + loc.offset); } - void* fd_ptr = NULL; - if (bpf_probe_read_user(&fd_ptr, sizeof(fd_ptr), conn_intf.ptr) != 0 || fd_ptr == NULL) { - return 0; - } - int32_t sysfd = 0; - bpf_probe_read_user(&sysfd, sizeof(sysfd), fd_ptr + symaddrs->FDSysFDOffset); - return sysfd; + } } -SEC("uprobe") -int probe_entry_tls_conn_write(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - uint32_t tgid = id >> 32; - - struct tgid_goid_t tgid_goid = {}; - tgid_goid.tgid = tgid; - - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_write FIRED tgid=%lu", tgid); - } +static __inline int32_t get_fd_from_conn_intf_core(struct go_interface conn_intf, + const struct go_symaddrs_t* symaddrs) { - uint64_t goid = get_goid(ctx); + bpf_probe_read(&conn_intf, sizeof(conn_intf), conn_intf.ptr + symaddrs->TLSConnOffset); - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_write goid=%llu tgid=%lu", goid, tgid); - } - - if (goid == 0) { - return 0; - } - tgid_goid.goid = goid; - - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_write 1 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } - - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { + if (conn_intf.type != symaddrs->TCPConnOffset) { return 0; } - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + void* fd_ptr; + bpf_probe_read(&fd_ptr, sizeof(fd_ptr), conn_intf.ptr); + __u64 sysfd; + bpf_probe_read(&sysfd, sizeof(sysfd), fd_ptr + symaddrs->FDSysFDOffset); + return sysfd; +} - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_write 2 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } +int probe_entry_tls_conn_write(struct pt_regs* ctx) { + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; + uint32_t pid = id; + + struct tgid_goid_t tgid_goid = {}; + tgid_goid.tgid = tgid; + uint64_t goid = get_goid(ctx); + if (goid == 0) { + return 0; + } + tgid_goid.goid = goid; - struct go_tls_conn_args args = {}; - assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), - symaddrs->WriteConnectionLoc, sp, regs); - assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), - symaddrs->WriteBufferLoc, sp, regs); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_write 1 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - bpf_map_update_elem(&active_tls_conn_op_map, &tgid_goid, &args, BPF_ANY); + struct go_symaddrs_t* symaddrs = go_symaddrs_table.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_write 3 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + const void* sp = (const void*)ctx->sp; + uint64_t* regs = go_regabi_regs(ctx); + if (regs == NULL) { return 0; -} + } -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) { - return 0; - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_write 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } + + struct go_tls_conn_args args = {}; + assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), symaddrs->WriteConnectionLoc, sp, regs); + assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), symaddrs->WriteBufferLoc, sp, regs); - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } + active_tls_conn_op_map.update(&tgid_goid, &args); - int64_t retval0 = 0; - assign_arg(&retval0, sizeof(retval0), symaddrs->WriteRet0Loc, sp, regs); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_write 3 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } + return 0; +} - struct go_interface retval1 = {}; - assign_arg(&retval1, sizeof(retval1), symaddrs->WriteRet1Loc, sp, regs); +static __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 = go_symaddrs_table.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 2.1 %llu %lu", id, tgid); - } + const void* sp = (const void*)ctx->sp; + uint64_t* regs = go_regabi_regs(ctx); + if (regs == NULL) { + return 0; + } - if (retval1.ptr != 0) { - return 0; - } + int64_t retval0 = 0; + assign_arg(&retval0, sizeof(retval0), symaddrs->WriteRet0Loc, sp, regs); - 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); - u32 fdu = (u32)fd; + struct go_interface retval1 = {}; + assign_arg(&retval1, sizeof(retval1), symaddrs->WriteRet1Loc, sp, regs); - if (print_bpf_logs) { - bpf_printk("TLS write fd: %d", fd); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 2.1 %llu %lu", id, tgid); + } + // If function returns an error, then there's no data to trace. + if (retval1.ptr != 0) { + return 0; + } - if (fd <= 0) { - return 0; - } + // To call get_fd_from_conn_intf, cast the conn_ptr into a go_interface. + 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); + u32 fdu = (u32)fd; + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("TLS : %lu", fdu); + } - set_conn_as_ssl(tgid, fdu); - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 2.2 %llu %lu", id, tgid); - } + set_conn_as_ssl(tgid, fdu); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 2.2 %llu %lu", id, tgid); + } - struct data_args_t data_args; - data_args.source_fn = kGoTLSWrite; - data_args.buf = args->plaintext_ptr; - data_args.fd = fd; + struct data_args_t data_args; + data_args.source_fn = kGoTLSWrite; + data_args.buf = args->plaintext_ptr; + data_args.fd = fd; - process_syscall_data(ctx, &data_args, id, true, true); + process_syscall_data(ctx, &data_args, id, true, /* ssl */ true); - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 2.3 %llu %lu", id, tgid); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 2.3 %llu %lu", id, tgid); + } - return 0; + return 0; } -SEC("uprobe") int probe_return_tls_conn_write(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - uint32_t tgid = id >> 32; - struct tgid_goid_t tgid_goid = {}; - tgid_goid.tgid = tgid; - uint64_t goid = get_goid(ctx); - if (goid == 0) { - return 0; - } - tgid_goid.goid = goid; + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; + uint32_t pid = id; - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 1 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + struct tgid_goid_t tgid_goid = {}; + tgid_goid.tgid = tgid; + uint64_t goid = get_goid(ctx); + if (goid == 0) { + return 0; + } + tgid_goid.goid = goid; - struct go_tls_conn_args* args = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); - if (args == NULL) { - return 0; - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 1 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 2 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + struct go_tls_conn_args* args = active_tls_conn_op_map.lookup(&tgid_goid); + if (args == NULL) { + return 0; + } - probe_return_tls_conn_write_core(ctx, id, tgid, args); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - bpf_map_delete_elem(&active_tls_conn_op_map, &tgid_goid); + probe_return_tls_conn_write_core(ctx, id, tgid, args); - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_write 3 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } - return 0; + active_tls_conn_op_map.delete(&tgid_goid); + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_write 3 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } + return 0; } -SEC("uprobe") int probe_entry_tls_conn_read(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - uint32_t tgid = id >> 32; - - struct tgid_goid_t tgid_goid = {}; - tgid_goid.tgid = tgid; - uint64_t goid = get_goid(ctx); - if (goid == 0) { - return 0; - } - tgid_goid.goid = goid; + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; + uint32_t pid = id; + + struct tgid_goid_t tgid_goid = {}; + tgid_goid.tgid = tgid; + uint64_t goid = get_goid(ctx); + if (goid == 0) { + return 0; + } + tgid_goid.goid = goid; - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_read 1 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_read 1 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - struct go_symaddrs_t* symaddrs = bpf_map_lookup_elem(&go_symaddrs_table, &tgid); - if (symaddrs == NULL) { - return 0; - } + struct go_symaddrs_t* symaddrs = go_symaddrs_table.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } - 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*)ctx->sp; + uint64_t* regs = go_regabi_regs(ctx); + if (regs == NULL) { + return 0; + } - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_read 2 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_read 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } + + struct go_tls_conn_args args = {}; + assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), symaddrs->ReadConnectionLoc, sp, regs); + assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), symaddrs->ReadBufferLoc, sp, regs); - struct go_tls_conn_args args = {}; - assign_arg(&args.conn_ptr, sizeof(args.conn_ptr), - symaddrs->ReadConnectionLoc, sp, regs); - assign_arg(&args.plaintext_ptr, sizeof(args.plaintext_ptr), - symaddrs->ReadBufferLoc, sp, regs); + active_tls_conn_op_map.update(&tgid_goid, &args); - bpf_map_update_elem(&active_tls_conn_op_map, &tgid_goid, &args, BPF_ANY); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_entry_tls_conn_read 3 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - if (print_bpf_logs) { - bpf_printk("probe_entry_tls_conn_read 3 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } - - return 0; + return 0; } -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) { - return 0; - } - - const void* sp = (const void*)PT_REGS_SP(ctx); - uint64_t* regs = go_regabi_regs(ctx); - if (regs == NULL) { - return 0; - } - - int64_t retval0 = 0; - assign_arg(&retval0, sizeof(retval0), symaddrs->ReadRet0Loc, sp, regs); +static __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 = go_symaddrs_table.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } - struct go_interface retval1 = {}; - assign_arg(&retval1, sizeof(retval1), symaddrs->ReadRet1Loc, sp, regs); + const void* sp = (const void*)ctx->sp; + uint64_t* regs = go_regabi_regs(ctx); + if (regs == NULL) { + return 0; + } - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_read 2.1 %llu %lu", id, tgid); - } + int64_t retval0 = 0; + assign_arg(&retval0, sizeof(retval0), symaddrs->ReadRet0Loc, sp, regs); - if (retval1.ptr != 0) { - return 0; - } + struct go_interface retval1 = {}; + assign_arg(&retval1, sizeof(retval1), symaddrs->ReadRet1Loc, sp, regs); - 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); - u32 fdu = (u32)fd; + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 2.1 %llu %lu", id, tgid); + } - if (print_bpf_logs) { - bpf_printk("TLS read fd: %d", fd); - } + // If function returns an error, then there's no data to trace. + if (retval1.ptr != 0) { + return 0; + } - if (fd <= 0) { - return 0; - } + // To call get_fd_from_conn_intf, cast the conn_ptr into a go_interface. + 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); + u32 fdu = (u32)fd; + + if(PRINT_BPF_LOGS){ + bpf_trace_printk("TLS : %lu", fdu); + } - set_conn_as_ssl(tgid, fdu); - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_read 2.2 %llu %lu", id, tgid); - } + set_conn_as_ssl(tgid, fdu); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 2.2 %llu %lu", id, tgid); + } - struct data_args_t data_args; - data_args.source_fn = kGoTLSRead; - data_args.buf = args->plaintext_ptr; - data_args.fd = fd; + struct data_args_t data_args; + data_args.source_fn = kGoTLSRead; + data_args.buf = args->plaintext_ptr; + data_args.fd = fd; - process_syscall_data(ctx, &data_args, id, false, true); + process_syscall_data(ctx, &data_args, id, false, /* ssl */ true); - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_read 2.3 %llu %lu", id, tgid); - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 2.3 %llu %lu", id, tgid); + } - return 0; + return 0; } -SEC("uprobe") int probe_return_tls_conn_read(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - uint32_t tgid = id >> 32; + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; + uint32_t pid = id; + + struct tgid_goid_t tgid_goid = {}; + tgid_goid.tgid = tgid; + uint64_t goid = get_goid(ctx); + if (goid == 0) { + return 0; + } + tgid_goid.goid = goid; - struct tgid_goid_t tgid_goid = {}; - tgid_goid.tgid = tgid; - uint64_t goid = get_goid(ctx); - if (goid == 0) { - return 0; - } - tgid_goid.goid = goid; + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 1 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_read 1 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } + struct go_tls_conn_args* args = active_tls_conn_op_map.lookup(&tgid_goid); + if (args == NULL) { + return 0; + } - struct go_tls_conn_args* args = bpf_map_lookup_elem(&active_tls_conn_op_map, &tgid_goid); - if (args == NULL) { - return 0; - } + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 2 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } - 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); + active_tls_conn_op_map.delete(&tgid_goid); - bpf_map_delete_elem(&active_tls_conn_op_map, &tgid_goid); + if(PRINT_BPF_LOGS){ + bpf_trace_printk("probe_return_tls_conn_read 3 %lu %llu", tgid_goid.tgid, tgid_goid.goid); + } + return 0; +} - if (print_bpf_logs) { - bpf_printk("probe_return_tls_conn_read 3 %lu %llu", - tgid_goid.tgid, tgid_goid.goid); - } - return 0; +static __inline void* get_tls_wrap_for_memfn() { + uint64_t id = bpf_get_current_pid_tgid(); + void** args = active_TLSWrap_memfn_this.lookup(&id); + if (args == NULL) { + return NULL; + } + return *args; } -/* =================================================================== - * Node.js TLS wrap probes - * =================================================================== */ +static __inline void update_node_ssl_tls_wrap_map(void* ssl) { + void* tls_wrap = get_tls_wrap_for_memfn(); + if (tls_wrap == NULL) { + return; + } + node_ssl_tls_wrap_map.update(&ssl, &tls_wrap); +} -SEC("uprobe") int probe_ret_SSL_new(struct pt_regs* ctx) { - void* ssl = (void*)PT_REGS_RC(ctx); - if (ssl == NULL) { - return 0; - } - uint64_t id = bpf_get_current_pid_tgid(); - uint32_t tgid = id >> 32; + void* ssl = (void*)PT_REGS_RC(ctx); + if (ssl == NULL) { + return 0; + } + uint64_t id = bpf_get_current_pid_tgid(); + uint32_t tgid = id >> 32; - struct node_tlswrap_symaddrs_t* symaddrs = - bpf_map_lookup_elem(&node_tlswrap_symaddrs_map, &tgid); - if (symaddrs == NULL) { - return 0; - } + struct node_tlswrap_symaddrs_t* symaddrs = node_tlswrap_symaddrs_map.lookup(&tgid); + if (symaddrs == NULL) { + return 0; + } - /* update_node_ssl_tls_wrap_map inlined */ - __u64* tls_wrap_val = bpf_map_lookup_elem(&active_TLSWrap_memfn_this, &id); - if (tls_wrap_val != NULL) { - __u64 ssl_key = (__u64)ssl; - __u64 tls_wrap_copy = *tls_wrap_val; - bpf_map_update_elem(&node_ssl_tls_wrap_map, &ssl_key, &tls_wrap_copy, BPF_ANY); - } + update_node_ssl_tls_wrap_map(ssl); - return 0; + return 0; } -SEC("uprobe") int probe_entry_TLSWrap_memfn(struct pt_regs* ctx) { - __u64 tls_wrap = (__u64)PT_REGS_PARM1(ctx); - uint64_t id = bpf_get_current_pid_tgid(); - bpf_map_update_elem(&active_TLSWrap_memfn_this, &id, &tls_wrap, BPF_ANY); - return 0; + void* tls_wrap = (void*)PT_REGS_PARM1(ctx); + uint64_t id = bpf_get_current_pid_tgid(); + active_TLSWrap_memfn_this.update(&id, &tls_wrap); + return 0; } -SEC("uprobe") int probe_ret_TLSWrap_memfn(struct pt_regs* ctx) { - uint64_t id = bpf_get_current_pid_tgid(); - bpf_map_delete_elem(&active_TLSWrap_memfn_this, &id); - return 0; -} + uint64_t id = bpf_get_current_pid_tgid(); + active_TLSWrap_memfn_this.delete(&id); + return 0; +} \ No newline at end of file