From a6845d42613994a9270964e12489dd889ddefa4c Mon Sep 17 00:00:00 2001 From: "M. Mert Yildiran" Date: Thu, 30 Jun 2022 20:32:00 +0300 Subject: [PATCH] Define `goid_offsets`, `goid_offsets_map` structs and pass the offsets correctly --- tap/tlstapper/bpf/go_uprobes.c | 10 +++++----- tap/tlstapper/bpf/include/maps.h | 9 ++++++++- tap/tlstapper/go_hooks.go | 12 +++++++----- tap/tlstapper/go_offsets.go | 4 +++- tap/tlstapper/tls_tapper.go | 2 +- tap/tlstapper/tlstapper_bpfel_x86.go | 11 ++++++++--- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/tap/tlstapper/bpf/go_uprobes.c b/tap/tlstapper/bpf/go_uprobes.c index e38342d40..96dca6ffc 100644 --- a/tap/tlstapper/bpf/go_uprobes.c +++ b/tap/tlstapper/bpf/go_uprobes.c @@ -76,9 +76,8 @@ enum ABI { static __always_inline __u32 get_goid_from_thread_local_storage(__u64 *goroutine_id) { int zero = 0; int one = 1; - __u32* g_addr_offset = bpf_map_lookup_elem(&goid_offset_map, &zero); - __u32* goid_offset = bpf_map_lookup_elem(&goid_offset_map, &one); - if (g_addr_offset == NULL || goid_offset == NULL) { + struct goid_offsets* offsets = bpf_map_lookup_elem(&goid_offsets_map, &zero); + if (offsets == NULL) { return 0; } @@ -104,8 +103,8 @@ static __always_inline __u32 get_goid_from_thread_local_storage(__u64 *goroutine // Get the Goroutine ID (goid) which is stored in thread-local storage. size_t g_addr; - bpf_probe_read_user(&g_addr, sizeof(void *), (void*)(task->thread.fsbase + *g_addr_offset)); - bpf_probe_read_user(goroutine_id, sizeof(void *), (void*)(g_addr + *goid_offset)); + bpf_probe_read_user(&g_addr, sizeof(void *), (void*)(task->thread.fsbase + offsets->g_addr_offset)); + bpf_probe_read_user(goroutine_id, sizeof(void *), (void*)(g_addr + offsets->goid_offset)); bpf_ringbuf_discard(task, BPF_RB_FORCE_WAKEUP); return 1; @@ -162,6 +161,7 @@ static __always_inline void go_crypto_tls_uprobe(struct pt_regs *ctx, struct bpf } #else if (abi == ABI0) { + // bpf_printk("[go_crypto_tls_uprobe] It's ABI0"); err = bpf_probe_read(&info.buffer_len, sizeof(__u32), (void*)GO_ABI_0_PT_REGS_SP(ctx)+0x18); if (err != 0) { log_error(ctx, LOG_ERROR_READING_BYTES_COUNT, pid_tgid, err, ORIGIN_SSL_UPROBE_CODE); diff --git a/tap/tlstapper/bpf/include/maps.h b/tap/tlstapper/bpf/include/maps.h index 83d4dd3c4..3a9716f42 100644 --- a/tap/tlstapper/bpf/include/maps.h +++ b/tap/tlstapper/bpf/include/maps.h @@ -53,6 +53,13 @@ struct fd_info { __u8 flags; }; +struct goid_offsets { + __u64 g_addr_offset; + __u64 goid_offset; +}; + +const struct goid_offsets *unused __attribute__((unused)); + // Heap-like area for eBPF programs - stack size limited to 512 bytes, we must use maps for bigger (chunk) objects. // struct { @@ -91,7 +98,7 @@ BPF_LRU_HASH(openssl_write_context, __u64, struct ssl_info); BPF_LRU_HASH(openssl_read_context, __u64, struct ssl_info); // Go specific -BPF_HASH(goid_offset_map, __u32, __u64); +BPF_HASH(goid_offsets_map, __u32, struct goid_offsets); BPF_LRU_HASH(go_write_context, __u64, struct ssl_info); BPF_LRU_HASH(go_read_context, __u64, struct ssl_info); diff --git a/tap/tlstapper/go_hooks.go b/tap/tlstapper/go_hooks.go index 6fa2c81ae..bf0cae833 100644 --- a/tap/tlstapper/go_hooks.go +++ b/tap/tlstapper/go_hooks.go @@ -88,11 +88,13 @@ func (s *goHooks) installHooks(bpfObjects *tlsTapperObjects, ex *link.Executable } // Pass goid and g struct offsets to an eBPF map to retrieve it in eBPF context - goidOffsetMap := bpfObjects.tlsTapperMaps.GoidOffsetMap - if err := goidOffsetMap.Put(uint32(0), offsets.GStructOffset); err != nil { - return errors.Wrap(err, 0) - } - if err := goidOffsetMap.Put(uint32(1), offsets.GoidOffset); err != nil { + if err := bpfObjects.tlsTapperMaps.GoidOffsetsMap.Put( + uint32(0), + tlsTapperGoidOffsets{ + G_addrOffset: offsets.GStructOffset, + GoidOffset: offsets.GoidOffset, + }, + ); err != nil { return errors.Wrap(err, 0) } diff --git a/tap/tlstapper/go_offsets.go b/tap/tlstapper/go_offsets.go index 6e6383fe8..c69d2a42c 100644 --- a/tap/tlstapper/go_offsets.go +++ b/tap/tlstapper/go_offsets.go @@ -167,6 +167,7 @@ func getGoidOffset(elfFile *elf.File) (goidOffset uint64, gStructOffset uint64, entryReader := dwarfData.Reader() + var runtimeGOffset uint64 var seenRuntimeG bool for { @@ -185,6 +186,7 @@ func getGoidOffset(elfFile *elf.File) (goidOffset uint64, gStructOffset uint64, if field.Attr == dwarf.AttrName { val := field.Val.(string) if val == "runtime.g" { + runtimeGOffset = uint64(entry.Offset) seenRuntimeG = true } } @@ -198,7 +200,7 @@ func getGoidOffset(elfFile *elf.File) (goidOffset uint64, gStructOffset uint64, if field.Attr == dwarf.AttrName { val := field.Val.(string) if val == "goid" { - goidOffset = uint64(entry.Offset) + goidOffset = uint64(entry.Offset) - runtimeGOffset - 0x4b gStructOffset, err = getGStructOffset(elfFile) return } diff --git a/tap/tlstapper/tls_tapper.go b/tap/tlstapper/tls_tapper.go index a46275719..604d418c4 100644 --- a/tap/tlstapper/tls_tapper.go +++ b/tap/tlstapper/tls_tapper.go @@ -12,7 +12,7 @@ import ( const GlobalTapPid = 0 -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@v0.9.0 -target $BPF_TARGET -cflags $BPF_CFLAGS -type tls_chunk tlsTapper bpf/tls_tapper.c +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go@v0.9.0 -target $BPF_TARGET -cflags $BPF_CFLAGS -type tls_chunk -type goid_offsets tlsTapper bpf/tls_tapper.c type TlsTapper struct { bpfObjects tlsTapperObjects diff --git a/tap/tlstapper/tlstapper_bpfel_x86.go b/tap/tlstapper/tlstapper_bpfel_x86.go index e544c1546..6e58a6463 100644 --- a/tap/tlstapper/tlstapper_bpfel_x86.go +++ b/tap/tlstapper/tlstapper_bpfel_x86.go @@ -13,6 +13,11 @@ import ( "github.com/cilium/ebpf" ) +type tlsTapperGoidOffsets struct { + G_addrOffset uint64 + GoidOffset uint64 +} + type tlsTapperTlsChunk struct { Pid uint32 Tgid uint32 @@ -100,7 +105,7 @@ type tlsTapperMapSpecs struct { FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` GoReadContext *ebpf.MapSpec `ebpf:"go_read_context"` GoWriteContext *ebpf.MapSpec `ebpf:"go_write_context"` - GoidOffsetMap *ebpf.MapSpec `ebpf:"goid_offset_map"` + GoidOffsetsMap *ebpf.MapSpec `ebpf:"goid_offsets_map"` Heap *ebpf.MapSpec `ebpf:"heap"` LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` OpensslReadContext *ebpf.MapSpec `ebpf:"openssl_read_context"` @@ -134,7 +139,7 @@ type tlsTapperMaps struct { FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` GoReadContext *ebpf.Map `ebpf:"go_read_context"` GoWriteContext *ebpf.Map `ebpf:"go_write_context"` - GoidOffsetMap *ebpf.Map `ebpf:"goid_offset_map"` + GoidOffsetsMap *ebpf.Map `ebpf:"goid_offsets_map"` Heap *ebpf.Map `ebpf:"heap"` LogBuffer *ebpf.Map `ebpf:"log_buffer"` OpensslReadContext *ebpf.Map `ebpf:"openssl_read_context"` @@ -151,7 +156,7 @@ func (m *tlsTapperMaps) Close() error { m.FileDescriptorToIpv4, m.GoReadContext, m.GoWriteContext, - m.GoidOffsetMap, + m.GoidOffsetsMap, m.Heap, m.LogBuffer, m.OpensslReadContext,