diff --git a/tap/tlstapper/bpf/common.c b/tap/tlstapper/bpf/common.c index 0719019d9..1cf80152b 100644 --- a/tap/tlstapper/bpf/common.c +++ b/tap/tlstapper/bpf/common.c @@ -145,14 +145,16 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf send_chunk(ctx, info->buffer, id, chunk); } +static __always_inline struct ssl_info new_ssl_info() { + struct ssl_info info = { .fd = invalid_fd, .created_at_nano = bpf_ktime_get_ns() }; + return info; +} + static __always_inline struct ssl_info lookup_ssl_info(struct pt_regs *ctx, struct bpf_map_def* map_fd, __u64 pid_tgid) { struct ssl_info *infoPtr = bpf_map_lookup_elem(map_fd, &pid_tgid); - struct ssl_info info = {}; + struct ssl_info info = new_ssl_info(); - if (infoPtr == NULL) { - info.fd = invalid_fd; - info.created_at_nano = bpf_ktime_get_ns(); - } else { + if (infoPtr != NULL) { long err = bpf_probe_read(&info, sizeof(struct ssl_info), infoPtr); if (err != 0) { diff --git a/tap/tlstapper/bpf/fd_tracepoints.c b/tap/tlstapper/bpf/fd_tracepoints.c index 88add7f44..464da0ff0 100644 --- a/tap/tlstapper/bpf/fd_tracepoints.c +++ b/tap/tlstapper/bpf/fd_tracepoints.c @@ -28,7 +28,7 @@ void sys_enter_read(struct sys_enter_read_ctx *ctx) { return; } - struct ssl_info *infoPtr = bpf_map_lookup_elem(&ssl_read_context, &id); + struct ssl_info *infoPtr = bpf_map_lookup_elem(&openssl_read_context, &id); if (infoPtr == NULL) { return; @@ -44,7 +44,7 @@ void sys_enter_read(struct sys_enter_read_ctx *ctx) { info.fd = ctx->fd; - err = bpf_map_update_elem(&ssl_read_context, &id, &info, BPF_ANY); + err = bpf_map_update_elem(&openssl_read_context, &id, &info, BPF_ANY); if (err != 0) { log_error(ctx, LOG_ERROR_PUTTING_FILE_DESCRIPTOR, id, err, ORIGIN_SYS_ENTER_READ_CODE); @@ -68,7 +68,7 @@ void sys_enter_write(struct sys_enter_write_ctx *ctx) { return; } - struct ssl_info *infoPtr = bpf_map_lookup_elem(&ssl_write_context, &id); + struct ssl_info *infoPtr = bpf_map_lookup_elem(&openssl_write_context, &id); if (infoPtr == NULL) { return; @@ -84,7 +84,7 @@ void sys_enter_write(struct sys_enter_write_ctx *ctx) { info.fd = ctx->fd; - err = bpf_map_update_elem(&ssl_write_context, &id, &info, BPF_ANY); + err = bpf_map_update_elem(&openssl_write_context, &id, &info, BPF_ANY); if (err != 0) { log_error(ctx, LOG_ERROR_PUTTING_FILE_DESCRIPTOR, id, err, ORIGIN_SYS_ENTER_WRITE_CODE); diff --git a/tap/tlstapper/bpf/golang_uprobes.c b/tap/tlstapper/bpf/golang_uprobes.c index 03b3aaf2a..e526c49a7 100644 --- a/tap/tlstapper/bpf/golang_uprobes.c +++ b/tap/tlstapper/bpf/golang_uprobes.c @@ -81,13 +81,14 @@ static int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) { return 0; } - struct ssl_info info = lookup_ssl_info(ctx, &ssl_write_context, pid_tgid); + struct ssl_info info = new_ssl_info(); info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R2(ctx); info.buffer = (void*)GO_ABI_INTERNAL_PT_REGS_R4(ctx); info.fd = get_fd_from_tcp_conn(ctx); - long err = bpf_map_update_elem(&ssl_write_context, &pid_tgid, &info, BPF_ANY); + __u64 pid_fp = pid << 32 | GO_ABI_INTERNAL_PT_REGS_GP(ctx); + long err = bpf_map_update_elem(&go_write_context, &pid_fp, &info, BPF_ANY); if (err != 0) { log_error(ctx, LOG_ERROR_PUTTING_SSL_CONTEXT, pid_tgid, err, 0l); @@ -104,7 +105,8 @@ static int golang_crypto_tls_write_ex_uprobe(struct pt_regs *ctx) { return 0; } - struct ssl_info *info_ptr = bpf_map_lookup_elem(&ssl_write_context, &pid_tgid); + __u64 pid_fp = pid << 32 | GO_ABI_INTERNAL_PT_REGS_GP(ctx); + struct ssl_info *info_ptr = bpf_map_lookup_elem(&go_write_context, &pid_fp); if (info_ptr == NULL) { return 0; @@ -131,13 +133,14 @@ static int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) { return 0; } - struct ssl_info info = lookup_ssl_info(ctx, &ssl_read_context, pid_tgid); + struct ssl_info info = new_ssl_info(); info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R2(ctx); info.buffer = (void*)GO_ABI_INTERNAL_PT_REGS_R4(ctx); info.fd = get_fd_from_tcp_conn(ctx); - long err = bpf_map_update_elem(&ssl_read_context, &pid_tgid, &info, BPF_ANY); + __u64 pid_fp = pid << 32 | GO_ABI_INTERNAL_PT_REGS_GP(ctx); + long err = bpf_map_update_elem(&go_read_context, &pid_fp, &info, BPF_ANY); if (err != 0) { log_error(ctx, LOG_ERROR_PUTTING_SSL_CONTEXT, pid_tgid, err, 0l); @@ -154,7 +157,8 @@ static int golang_crypto_tls_read_ex_uprobe(struct pt_regs *ctx) { return 0; } - struct ssl_info *info_ptr = bpf_map_lookup_elem(&ssl_read_context, &pid_tgid); + __u64 pid_fp = pid << 32 | GO_ABI_INTERNAL_PT_REGS_GP(ctx); + struct ssl_info *info_ptr = bpf_map_lookup_elem(&go_read_context, &pid_fp); if (info_ptr == NULL) { return 0; diff --git a/tap/tlstapper/bpf/include/common.h b/tap/tlstapper/bpf/include/common.h index c145e08dd..86e49b867 100644 --- a/tap/tlstapper/bpf/include/common.h +++ b/tap/tlstapper/bpf/include/common.h @@ -14,6 +14,7 @@ static int add_address_to_chunk(struct pt_regs *ctx, struct tls_chunk* chunk, __ static void send_chunk_part(struct pt_regs *ctx, __u8* buffer, __u64 id, struct tls_chunk* chunk, int start, int end); static void send_chunk(struct pt_regs *ctx, __u8* buffer, __u64 id, struct tls_chunk* chunk); static void output_ssl_chunk(struct pt_regs *ctx, struct ssl_info* info, int count_bytes, __u64 id, __u32 flags); +static struct ssl_info new_ssl_info(); static struct ssl_info lookup_ssl_info(struct pt_regs *ctx, struct bpf_map_def* map_fd, __u64 pid_tgid); #endif /* __COMMON__ */ diff --git a/tap/tlstapper/bpf/include/go_abi_internal.h b/tap/tlstapper/bpf/include/go_abi_internal.h index d96f658dc..5303ea751 100644 --- a/tap/tlstapper/bpf/include/go_abi_internal.h +++ b/tap/tlstapper/bpf/include/go_abi_internal.h @@ -72,6 +72,8 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/AMD6 #define GO_ABI_INTERNAL_PT_REGS_P5(x) 0 #define GO_ABI_INTERNAL_PT_REGS_P6(x) 0 #define GO_ABI_INTERNAL_PT_REGS_SP(x) ((x)->esp) +#define GO_ABI_INTERNAL_PT_REGS_FP(x) ((x)->ebp) +#define GO_ABI_INTERNAL_PT_REGS_GP(x) ((x)->e14) #else @@ -82,6 +84,8 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/AMD6 #define GO_ABI_INTERNAL_PT_REGS_R5(x) ((x)->rbp) #define GO_ABI_INTERNAL_PT_REGS_R6(x) ((x)->rsi) #define GO_ABI_INTERNAL_PT_REGS_SP(x) ((x)->rsp) +#define GO_ABI_INTERNAL_PT_REGS_FP(x) ((x)->rbp) +#define GO_ABI_INTERNAL_PT_REGS_GP(x) ((x)->r14) #endif @@ -98,6 +102,8 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/ARM6 #define GO_ABI_INTERNAL_PT_REGS_R5(x) ((x)->uregs[4]) #define GO_ABI_INTERNAL_PT_REGS_R6(x) ((x)->uregs[5]) #define GO_ABI_INTERNAL_PT_REGS_SP(x) ((x)->uregs[14]) +#define GO_ABI_INTERNAL_PT_REGS_FP(x) ((x)->uregs[29]) +#define GO_ABI_INTERNAL_PT_REGS_GP(x) ((x)->uregs[28]) #elif defined(bpf_target_arm64) @@ -111,6 +117,8 @@ struct pt_regs; #define GO_ABI_INTERNAL_PT_REGS_R5(x) (((PT_REGS_ARM64 *)(x))->regs[4]) #define GO_ABI_INTERNAL_PT_REGS_R6(x) (((PT_REGS_ARM64 *)(x))->regs[5]) #define GO_ABI_INTERNAL_PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->regs[30]) +#define GO_ABI_INTERNAL_PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29]) +#define GO_ABI_INTERNAL_PT_REGS_GP(x) (((PT_REGS_ARM64 *)(x))->regs[28]) #elif defined(bpf_target_powerpc) @@ -125,6 +133,8 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/PPC6 #define GO_ABI_INTERNAL_PT_REGS_R5(x) ((x)->gpr[7]) #define GO_ABI_INTERNAL_PT_REGS_R6(x) ((x)->gpr[8]) #define GO_ABI_INTERNAL_PT_REGS_SP(x) ((x)->sp) +#define GO_ABI_INTERNAL_PT_REGS_FP(x) ((x)->gpr[12]) +#define GO_ABI_INTERNAL_PT_REGS_GP(x) ((x)->gpr[30]) #endif diff --git a/tap/tlstapper/bpf/include/maps.h b/tap/tlstapper/bpf/include/maps.h index b9fe5966b..f8c799d13 100644 --- a/tap/tlstapper/bpf/include/maps.h +++ b/tap/tlstapper/bpf/include/maps.h @@ -80,11 +80,18 @@ struct { #define BPF_LRU_HASH(_name, _key_type, _value_type) \ BPF_MAP(_name, BPF_MAP_TYPE_LRU_HASH, _key_type, _value_type, MAX_ENTRIES_LRU_HASH) +// Generic BPF_HASH(pids_map, __u32, __u32); -BPF_LRU_HASH(ssl_write_context, __u64, struct ssl_info); -BPF_LRU_HASH(ssl_read_context, __u64, struct ssl_info); BPF_LRU_HASH(file_descriptor_to_ipv4, __u64, struct fd_info); BPF_PERF_OUTPUT(chunks_buffer); BPF_PERF_OUTPUT(log_buffer); +// OpenSSL specific +BPF_LRU_HASH(openssl_write_context, __u64, struct ssl_info); +BPF_LRU_HASH(openssl_read_context, __u64, struct ssl_info); + +// Go specific +BPF_LRU_HASH(go_write_context, __u64, struct ssl_info); +BPF_LRU_HASH(go_read_context, __u64, struct ssl_info); + #endif /* __MAPS__ */ diff --git a/tap/tlstapper/bpf/openssl_uprobes.c b/tap/tlstapper/bpf/openssl_uprobes.c index bd9db10d6..df6d511cb 100644 --- a/tap/tlstapper/bpf/openssl_uprobes.c +++ b/tap/tlstapper/bpf/openssl_uprobes.c @@ -21,7 +21,7 @@ static __always_inline void ssl_uprobe(struct pt_regs *ctx, void* ssl, void* buf } struct ssl_info *infoPtr = bpf_map_lookup_elem(map_fd, &id); - struct ssl_info info = lookup_ssl_info(ctx, &ssl_write_context, id); + struct ssl_info info = lookup_ssl_info(ctx, &openssl_write_context, id); info.count_ptr = count_ptr; info.buffer = buffer; @@ -79,40 +79,40 @@ static __always_inline void ssl_uretprobe(struct pt_regs *ctx, struct bpf_map_de SEC("uprobe/ssl_write") void BPF_KPROBE(ssl_write, void* ssl, void* buffer, int num) { - ssl_uprobe(ctx, ssl, buffer, num, &ssl_write_context, 0); + ssl_uprobe(ctx, ssl, buffer, num, &openssl_write_context, 0); } SEC("uretprobe/ssl_write") void BPF_KPROBE(ssl_ret_write) { - ssl_uretprobe(ctx, &ssl_write_context, 0); + ssl_uretprobe(ctx, &openssl_write_context, 0); } SEC("uprobe/ssl_read") void BPF_KPROBE(ssl_read, void* ssl, void* buffer, int num) { - ssl_uprobe(ctx, ssl, buffer, num, &ssl_read_context, 0); + ssl_uprobe(ctx, ssl, buffer, num, &openssl_read_context, 0); } SEC("uretprobe/ssl_read") void BPF_KPROBE(ssl_ret_read) { - ssl_uretprobe(ctx, &ssl_read_context, FLAGS_IS_READ_BIT); + ssl_uretprobe(ctx, &openssl_read_context, FLAGS_IS_READ_BIT); } SEC("uprobe/ssl_write_ex") void BPF_KPROBE(ssl_write_ex, void* ssl, void* buffer, size_t num, size_t *written) { - ssl_uprobe(ctx, ssl, buffer, num, &ssl_write_context, written); + ssl_uprobe(ctx, ssl, buffer, num, &openssl_write_context, written); } SEC("uretprobe/ssl_write_ex") void BPF_KPROBE(ssl_ret_write_ex) { - ssl_uretprobe(ctx, &ssl_write_context, 0); + ssl_uretprobe(ctx, &openssl_write_context, 0); } SEC("uprobe/ssl_read_ex") void BPF_KPROBE(ssl_read_ex, void* ssl, void* buffer, size_t num, size_t *readbytes) { - ssl_uprobe(ctx, ssl, buffer, num, &ssl_read_context, readbytes); + ssl_uprobe(ctx, ssl, buffer, num, &openssl_read_context, readbytes); } SEC("uretprobe/ssl_read_ex") void BPF_KPROBE(ssl_ret_read_ex) { - ssl_uretprobe(ctx, &ssl_read_context, FLAGS_IS_READ_BIT); + ssl_uretprobe(ctx, &openssl_read_context, FLAGS_IS_READ_BIT); } diff --git a/tap/tlstapper/golang_hooks.go b/tap/tlstapper/golang_hooks.go index e6ef28be1..882b8a0b0 100644 --- a/tap/tlstapper/golang_hooks.go +++ b/tap/tlstapper/golang_hooks.go @@ -55,7 +55,9 @@ func (s *golangHooks) installHooks(bpfObjects *tlsTapperObjects, ex *link.Execut // Symbol points to // [`crypto/tls.(*Conn).Read`](https://github.com/golang/go/blob/go1.17.6/src/crypto/tls/conn.go#L1263) - s.golangReadProbe, err = ex.Uprobe(golangReadSymbol, bpfObjects.GolangCryptoTlsReadUprobe, nil) + s.golangReadProbe, err = ex.Uprobe(golangReadSymbol, bpfObjects.GolangCryptoTlsReadUprobe, &link.UprobeOptions{ + Offset: offsets.GolangReadOffset.enter, + }) if err != nil { return errors.Wrap(err, 0) diff --git a/tap/tlstapper/tlstapper_bpfeb.go b/tap/tlstapper/tlstapper_bpfeb.go index f06e78d9f..a0fd337e8 100644 --- a/tap/tlstapper/tlstapper_bpfeb.go +++ b/tap/tlstapper/tlstapper_bpfeb.go @@ -94,11 +94,13 @@ type tlsTapperMapSpecs struct { ChunksBuffer *ebpf.MapSpec `ebpf:"chunks_buffer"` ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` + GoReadContext *ebpf.MapSpec `ebpf:"go_read_context"` + GoWriteContext *ebpf.MapSpec `ebpf:"go_write_context"` Heap *ebpf.MapSpec `ebpf:"heap"` LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` + OpensslReadContext *ebpf.MapSpec `ebpf:"openssl_read_context"` + OpensslWriteContext *ebpf.MapSpec `ebpf:"openssl_write_context"` PidsMap *ebpf.MapSpec `ebpf:"pids_map"` - SslReadContext *ebpf.MapSpec `ebpf:"ssl_read_context"` - SslWriteContext *ebpf.MapSpec `ebpf:"ssl_write_context"` } // tlsTapperObjects contains all objects after they have been loaded into the kernel. @@ -124,11 +126,13 @@ type tlsTapperMaps struct { ChunksBuffer *ebpf.Map `ebpf:"chunks_buffer"` ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` + GoReadContext *ebpf.Map `ebpf:"go_read_context"` + GoWriteContext *ebpf.Map `ebpf:"go_write_context"` Heap *ebpf.Map `ebpf:"heap"` LogBuffer *ebpf.Map `ebpf:"log_buffer"` + OpensslReadContext *ebpf.Map `ebpf:"openssl_read_context"` + OpensslWriteContext *ebpf.Map `ebpf:"openssl_write_context"` PidsMap *ebpf.Map `ebpf:"pids_map"` - SslReadContext *ebpf.Map `ebpf:"ssl_read_context"` - SslWriteContext *ebpf.Map `ebpf:"ssl_write_context"` } func (m *tlsTapperMaps) Close() error { @@ -137,11 +141,13 @@ func (m *tlsTapperMaps) Close() error { m.ChunksBuffer, m.ConnectSyscallInfo, m.FileDescriptorToIpv4, + m.GoReadContext, + m.GoWriteContext, m.Heap, m.LogBuffer, + m.OpensslReadContext, + m.OpensslWriteContext, m.PidsMap, - m.SslReadContext, - m.SslWriteContext, ) } diff --git a/tap/tlstapper/tlstapper_bpfeb.o b/tap/tlstapper/tlstapper_bpfeb.o index a4c96155b..03709d1ef 100644 Binary files a/tap/tlstapper/tlstapper_bpfeb.o and b/tap/tlstapper/tlstapper_bpfeb.o differ diff --git a/tap/tlstapper/tlstapper_bpfel.go b/tap/tlstapper/tlstapper_bpfel.go index f1bbebe8d..7527af903 100644 --- a/tap/tlstapper/tlstapper_bpfel.go +++ b/tap/tlstapper/tlstapper_bpfel.go @@ -94,11 +94,13 @@ type tlsTapperMapSpecs struct { ChunksBuffer *ebpf.MapSpec `ebpf:"chunks_buffer"` ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` + GoReadContext *ebpf.MapSpec `ebpf:"go_read_context"` + GoWriteContext *ebpf.MapSpec `ebpf:"go_write_context"` Heap *ebpf.MapSpec `ebpf:"heap"` LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` + OpensslReadContext *ebpf.MapSpec `ebpf:"openssl_read_context"` + OpensslWriteContext *ebpf.MapSpec `ebpf:"openssl_write_context"` PidsMap *ebpf.MapSpec `ebpf:"pids_map"` - SslReadContext *ebpf.MapSpec `ebpf:"ssl_read_context"` - SslWriteContext *ebpf.MapSpec `ebpf:"ssl_write_context"` } // tlsTapperObjects contains all objects after they have been loaded into the kernel. @@ -124,11 +126,13 @@ type tlsTapperMaps struct { ChunksBuffer *ebpf.Map `ebpf:"chunks_buffer"` ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` + GoReadContext *ebpf.Map `ebpf:"go_read_context"` + GoWriteContext *ebpf.Map `ebpf:"go_write_context"` Heap *ebpf.Map `ebpf:"heap"` LogBuffer *ebpf.Map `ebpf:"log_buffer"` + OpensslReadContext *ebpf.Map `ebpf:"openssl_read_context"` + OpensslWriteContext *ebpf.Map `ebpf:"openssl_write_context"` PidsMap *ebpf.Map `ebpf:"pids_map"` - SslReadContext *ebpf.Map `ebpf:"ssl_read_context"` - SslWriteContext *ebpf.Map `ebpf:"ssl_write_context"` } func (m *tlsTapperMaps) Close() error { @@ -137,11 +141,13 @@ func (m *tlsTapperMaps) Close() error { m.ChunksBuffer, m.ConnectSyscallInfo, m.FileDescriptorToIpv4, + m.GoReadContext, + m.GoWriteContext, m.Heap, m.LogBuffer, + m.OpensslReadContext, + m.OpensslWriteContext, m.PidsMap, - m.SslReadContext, - m.SslWriteContext, ) } diff --git a/tap/tlstapper/tlstapper_bpfel.o b/tap/tlstapper/tlstapper_bpfel.o index c89abe4d8..b82a066b8 100644 Binary files a/tap/tlstapper/tlstapper_bpfel.o and b/tap/tlstapper/tlstapper_bpfel.o differ