mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-07-08 13:54:28 +00:00
Change golang_read_writes
map type from BPF_RINGBUF
to BPF_PERF_OUTPUT
This commit is contained in:
parent
e5a1de9c71
commit
32c566705a
@ -11,15 +11,22 @@ Copyright (C) UP9 Inc.
|
||||
#include "include/logger_messages.h"
|
||||
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, struct golang_read_write);
|
||||
} golang_heap SEC(".maps");
|
||||
|
||||
SEC("uprobe/golang_crypto_tls_write")
|
||||
static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
if (!should_tap(pid_tgid >> 32)) {
|
||||
__u64 pid = pid_tgid >> 32;
|
||||
if (!should_tap(pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* stack_addr = (void*)ctx->rsp;
|
||||
__u64 pid = pid_tgid >> 32;
|
||||
__u32 key_dial;
|
||||
// Address at ctx->rsp + 0x20 is common between golang_crypto_tls_write_uprobe and golang_net_http_dialconn_uprobe
|
||||
__u32 status = bpf_probe_read(&key_dial, sizeof(key_dial), stack_addr + 0x20);
|
||||
@ -36,10 +43,14 @@ static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
}
|
||||
|
||||
struct golang_read_write *b = NULL;
|
||||
b = bpf_ringbuf_reserve(&golang_read_writes, sizeof(struct golang_read_write), 0);
|
||||
int zero = 0;
|
||||
|
||||
b = bpf_map_lookup_elem(&golang_heap, &zero);
|
||||
|
||||
if (!b) {
|
||||
return 0;
|
||||
}
|
||||
log_error(ctx, LOG_ERROR_ALLOCATING_CHUNK, pid, 0l, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->pid = pid;
|
||||
b->fd = s->fd;
|
||||
@ -52,11 +63,10 @@ static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
status = bpf_probe_read(&b->data, CHUNK_SIZE, (void*)ctx->rbx);
|
||||
if (status < 0) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_WRITE_READING_DATA, pid_tgid, status, 0l);
|
||||
bpf_ringbuf_discard(b, BPF_RB_FORCE_WAKEUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_ringbuf_submit(b, 0);
|
||||
bpf_perf_event_output(ctx, &golang_read_writes, BPF_F_CURRENT_CPU, b, sizeof(struct golang_read_write));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -64,7 +74,8 @@ static __always_inline int golang_crypto_tls_write_uprobe(struct pt_regs *ctx) {
|
||||
SEC("uprobe/golang_crypto_tls_read")
|
||||
static __always_inline int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) {
|
||||
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
if (!should_tap(pid_tgid >> 32)) {
|
||||
__u64 pid = pid_tgid >> 32;
|
||||
if (!should_tap(pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -78,12 +89,16 @@ static __always_inline int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) {
|
||||
}
|
||||
|
||||
struct golang_read_write *b = NULL;
|
||||
b = bpf_ringbuf_reserve(&golang_read_writes, sizeof(struct golang_read_write), 0);
|
||||
if (!b) {
|
||||
return 0;
|
||||
}
|
||||
int zero = 0;
|
||||
|
||||
b->pid = pid_tgid >> 32;
|
||||
b = bpf_map_lookup_elem(&golang_heap, &zero);
|
||||
|
||||
if (!b) {
|
||||
log_error(ctx, LOG_ERROR_ALLOCATING_CHUNK, pid, 0l, 0l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
b->pid = pid;
|
||||
// ctx->rsi is common between golang_crypto_tls_write_uprobe and golang_crypto_tls_read_uprobe
|
||||
b->conn_addr = ctx->rsi; // go.itab.*net.TCPConn,net.Conn address
|
||||
b->is_request = false;
|
||||
@ -93,22 +108,21 @@ static __always_inline int golang_crypto_tls_read_uprobe(struct pt_regs *ctx) {
|
||||
status = bpf_probe_read(&b->data, CHUNK_SIZE, (void*)(data_p));
|
||||
if (status < 0) {
|
||||
log_error(ctx, LOG_ERROR_GOLANG_READ_READING_DATA, pid_tgid, status, 0l);
|
||||
bpf_ringbuf_discard(b, BPF_RB_FORCE_WAKEUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_ringbuf_submit(b, 0);
|
||||
bpf_perf_event_output(ctx, &golang_read_writes, BPF_F_CURRENT_CPU, b, sizeof(struct golang_read_write));
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("uprobe/golang_net_socket")
|
||||
static __always_inline int golang_net_socket_uprobe(struct pt_regs *ctx) {
|
||||
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||
if (!should_tap(pid_tgid >> 32)) {
|
||||
__u64 pid = pid_tgid >> 32;
|
||||
if (!should_tap(pid)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u64 pid = pid_tgid >> 32;
|
||||
// ctx->r14 is common between golang_net_socket_uprobe and golang_net_http_dialconn_uprobe
|
||||
__u64 key_socket = (pid << 32) + ctx->r14;
|
||||
struct golang_socket *s = bpf_map_lookup_elem(&golang_dial_to_socket, &key_socket);
|
||||
|
@ -95,12 +95,6 @@ const struct sys_close *unused2 __attribute__((unused));
|
||||
#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)
|
||||
|
||||
#define BPF_RINGBUF(_name) \
|
||||
struct { \
|
||||
__uint(type, BPF_MAP_TYPE_RINGBUF); \
|
||||
__uint(max_entries, MAX_ENTRIES_RINGBUFF); \
|
||||
} _name SEC(".maps"); \
|
||||
|
||||
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);
|
||||
@ -110,7 +104,7 @@ BPF_PERF_OUTPUT(log_buffer);
|
||||
|
||||
BPF_LRU_HASH(golang_dial_to_socket, __u64, struct golang_socket);
|
||||
BPF_LRU_HASH(golang_socket_to_write, __u64, struct golang_socket);
|
||||
BPF_RINGBUF(golang_read_writes);
|
||||
BPF_PERF_OUTPUT(golang_read_writes);
|
||||
BPF_PERF_OUTPUT(sys_closes);
|
||||
|
||||
#endif /* __MAPS__ */
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cilium/ebpf/perf"
|
||||
"github.com/cilium/ebpf/ringbuf"
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/hashicorp/golang-lru/simplelru"
|
||||
"github.com/up9inc/mizu/logger"
|
||||
@ -36,7 +35,7 @@ type tlsPoller struct {
|
||||
closedReaders chan string
|
||||
reqResMatcher api.RequestResponseMatcher
|
||||
chunksReader *perf.Reader
|
||||
golangReader *ringbuf.Reader
|
||||
golangReader *perf.Reader
|
||||
golangReadWriteMap *orderedmap.OrderedMap
|
||||
sysCloses *perf.Reader
|
||||
extension *api.Extension
|
||||
@ -76,7 +75,7 @@ func (p *tlsPoller) init(bpfObjects *tlsTapperObjects, bufferSize int) error {
|
||||
return errors.Wrap(err, 0)
|
||||
}
|
||||
|
||||
p.golangReader, err = ringbuf.NewReader(bpfObjects.GolangReadWrites)
|
||||
p.golangReader, err = perf.NewReader(bpfObjects.GolangReadWrites, bufferSize)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
@ -123,7 +122,7 @@ func (p *tlsPoller) pollGolang(emitter api.Emitter, options *api.TrafficFilterin
|
||||
go p.pollSysClose(p.sysCloses)
|
||||
}
|
||||
|
||||
func (p *tlsPoller) pollGolangReadWrite(rd *ringbuf.Reader, emitter api.Emitter, options *api.TrafficFilteringOptions,
|
||||
func (p *tlsPoller) pollGolangReadWrite(rd *perf.Reader, emitter api.Emitter, options *api.TrafficFilteringOptions,
|
||||
streamsMap api.TcpStreamMap) {
|
||||
nativeEndian := p.getByteOrder()
|
||||
// tlsTapperGolangReadWrite is generated by bpf2go.
|
||||
@ -131,17 +130,20 @@ func (p *tlsPoller) pollGolangReadWrite(rd *ringbuf.Reader, emitter api.Emitter,
|
||||
for {
|
||||
record, err := rd.Read()
|
||||
if err != nil {
|
||||
if errors.Is(err, ringbuf.ErrClosed) {
|
||||
log.Println("received signal, exiting..")
|
||||
if errors.Is(err, perf.ErrClosed) {
|
||||
return
|
||||
}
|
||||
log.Printf("reading from reader: %s", err)
|
||||
logger.Log.Errorf("reading from Golang tls reader: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if record.LostSamples != 0 {
|
||||
logger.Log.Infof("Golang perf event ring buffer full, dropped %d samples", record.LostSamples)
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse the ringbuf event entry into a tlsTapperGolangReadWrite structure.
|
||||
if err := binary.Read(bytes.NewBuffer(record.RawSample), nativeEndian, &b); err != nil {
|
||||
log.Printf("parsing ringbuf event: %s", err)
|
||||
logger.Log.Errorf("parsing Golang perf event: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -212,17 +214,17 @@ func (p *tlsPoller) pollSysClose(rd *perf.Reader) {
|
||||
if errors.Is(err, perf.ErrClosed) {
|
||||
return
|
||||
}
|
||||
log.Printf("reading from perf event reader: %s", err)
|
||||
logger.Log.Errorf("reading from sys_close tls reader: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if record.LostSamples != 0 {
|
||||
log.Printf("perf event ring buffer full, dropped %d samples", record.LostSamples)
|
||||
logger.Log.Info("sys_close perf event ring buffer full, dropped %d samples", record.LostSamples)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := binary.Read(bytes.NewBuffer(record.RawSample), nativeEndian, &b); err != nil {
|
||||
log.Printf("parsing perf event: %s", err)
|
||||
logger.Log.Errorf("parsing sys_close perf event: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ type tlsTapperMapSpecs struct {
|
||||
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"`
|
||||
GolangHeap *ebpf.MapSpec `ebpf:"golang_heap"`
|
||||
GolangReadWrites *ebpf.MapSpec `ebpf:"golang_read_writes"`
|
||||
GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.MapSpec `ebpf:"heap"`
|
||||
@ -143,6 +144,7 @@ type tlsTapperMaps struct {
|
||||
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"`
|
||||
GolangHeap *ebpf.Map `ebpf:"golang_heap"`
|
||||
GolangReadWrites *ebpf.Map `ebpf:"golang_read_writes"`
|
||||
GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.Map `ebpf:"heap"`
|
||||
@ -160,6 +162,7 @@ func (m *tlsTapperMaps) Close() error {
|
||||
m.ConnectSyscallInfo,
|
||||
m.FileDescriptorToIpv4,
|
||||
m.GolangDialToSocket,
|
||||
m.GolangHeap,
|
||||
m.GolangReadWrites,
|
||||
m.GolangSocketToWrite,
|
||||
m.Heap,
|
||||
|
Binary file not shown.
@ -109,6 +109,7 @@ type tlsTapperMapSpecs struct {
|
||||
ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.MapSpec `ebpf:"golang_dial_to_socket"`
|
||||
GolangHeap *ebpf.MapSpec `ebpf:"golang_heap"`
|
||||
GolangReadWrites *ebpf.MapSpec `ebpf:"golang_read_writes"`
|
||||
GolangSocketToWrite *ebpf.MapSpec `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.MapSpec `ebpf:"heap"`
|
||||
@ -143,6 +144,7 @@ type tlsTapperMaps struct {
|
||||
ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"`
|
||||
FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"`
|
||||
GolangDialToSocket *ebpf.Map `ebpf:"golang_dial_to_socket"`
|
||||
GolangHeap *ebpf.Map `ebpf:"golang_heap"`
|
||||
GolangReadWrites *ebpf.Map `ebpf:"golang_read_writes"`
|
||||
GolangSocketToWrite *ebpf.Map `ebpf:"golang_socket_to_write"`
|
||||
Heap *ebpf.Map `ebpf:"heap"`
|
||||
@ -160,6 +162,7 @@ func (m *tlsTapperMaps) Close() error {
|
||||
m.ConnectSyscallInfo,
|
||||
m.FileDescriptorToIpv4,
|
||||
m.GolangDialToSocket,
|
||||
m.GolangHeap,
|
||||
m.GolangReadWrites,
|
||||
m.GolangSocketToWrite,
|
||||
m.Heap,
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user