Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix uninitialized go connection info #1019

Merged
merged 5 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions bpf/go_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static __always_inline void read_ip_and_port(u8 *dst_ip, u16 *dst_port, void *sr
}
}

static __always_inline void get_conn_info_from_fd(void *fd_ptr, connection_info_t *info) {
static __always_inline u8 get_conn_info_from_fd(void *fd_ptr, connection_info_t *info) {
if (fd_ptr) {
void *laddr_ptr = 0;
void *raddr_ptr = 0;
Expand All @@ -251,20 +251,26 @@ static __always_inline void get_conn_info_from_fd(void *fd_ptr, connection_info_
// in Go we keep the original connection info order, since we only need it
// sorted when we make server requests or when we populate the trace_map for
// black box context propagation.

return 1;
}
}

return 0;
}

// HTTP black-box context propagation
static __always_inline void get_conn_info(void *conn_ptr, connection_info_t *info) {
static __always_inline u8 get_conn_info(void *conn_ptr, connection_info_t *info) {
if (conn_ptr) {
void *fd_ptr = 0;
bpf_probe_read(&fd_ptr, sizeof(fd_ptr), (void *)(conn_ptr + conn_fd_pos)); // find fd

bpf_dbg_printk("Found fd ptr %llx", fd_ptr);

get_conn_info_from_fd(fd_ptr, info);
return get_conn_info_from_fd(fd_ptr, info);
}

return 0;
}

#endif // GO_COMMON_H
9 changes: 5 additions & 4 deletions bpf/go_grpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ int uprobe_server_handleStream_return(struct pt_regs *ctx) {
bpf_probe_read(&conn_conn_ptr, sizeof(conn_conn_ptr), conn_ptr + 8);
bpf_dbg_printk("conn_conn_ptr %llx", conn_conn_ptr);
if (conn_conn_ptr) {
get_conn_info(conn_conn_ptr, &trace->conn);
found_conn = 1;
found_conn = get_conn_info(conn_conn_ptr, &trace->conn);
}
}
}
Expand Down Expand Up @@ -431,8 +430,10 @@ int uprobe_transport_http2Client_NewStream(struct pt_regs *ctx) {
bpf_dbg_printk("conn_conn_ptr %llx", conn_conn_ptr);
if (conn_conn_ptr) {
connection_info_t conn = {0};
get_conn_info(conn_conn_ptr, &conn);
bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY);
u8 ok = get_conn_info(conn_conn_ptr, &conn);
if (ok) {
bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY);
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions bpf/go_kafka_go.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ int uprobe_protocol_roundtrip_ret(struct pt_regs *ctx) {
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(p_ptr->conn_ptr + 8)); // find conn
bpf_dbg_printk("conn ptr %llx", conn_ptr);
if (conn_ptr) {
get_conn_info(conn_ptr, &trace->conn);
u8 ok = get_conn_info(conn_ptr, &trace->conn);
if (!ok) {
__builtin_memset(&trace->conn, 0, sizeof(connection_info_t));
}
}

__builtin_memcpy(trace->topic, topic_ptr->name, MAX_TOPIC_NAME_LEN);
Expand Down Expand Up @@ -237,7 +240,10 @@ int uprobe_reader_read(struct pt_regs *ctx) {
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(conn + 8)); // find conn
bpf_dbg_printk("conn ptr %llx", conn_ptr);
if (conn_ptr) {
get_conn_info(conn_ptr, &r.conn);
u8 ok = get_conn_info(conn_ptr, &r.conn);
if (!ok) {
__builtin_memset(&r.conn, 0, sizeof(connection_info_t));
}
}
}

Expand Down
24 changes: 13 additions & 11 deletions bpf/go_nethttp.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ int uprobe_ServeHTTPReturns(struct pt_regs *ctx) {
bpf_probe_read(&conn_conn_conn_ptr, sizeof(conn_conn_conn_ptr), conn_conn_ptr + 8);
bpf_dbg_printk("conn_conn_conn_ptr %llx", conn_conn_conn_ptr);

get_conn_info(conn_conn_conn_ptr, &trace->conn);
found_conn = 1;
found_conn = get_conn_info(conn_conn_conn_ptr, &trace->conn);
}
}

Expand Down Expand Up @@ -263,9 +262,10 @@ int uprobe_ServeHTTPReturns(struct pt_regs *ctx) {
void *conn_ptr = 0;
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(rwc_ptr + rwc_conn_pos)); // find conn
if (conn_ptr) {
get_conn_info(conn_ptr, &trace->conn);
found = 1;
bpf_dbg_printk("found backup connection info");
found = get_conn_info(conn_ptr, &trace->conn);
if (found) {
bpf_dbg_printk("found backup connection info");
}
//dbg_print_http_connection_info(&conn);
}
}
Expand Down Expand Up @@ -562,12 +562,14 @@ int uprobe_http2RoundTrip(struct pt_regs *ctx) {
bpf_dbg_printk("tconn_conn %llx", tconn_conn);

connection_info_t conn = {0};
get_conn_info(tconn_conn, &conn);
u8 ok = get_conn_info(tconn_conn, &conn);

void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
if (ok) {
void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);

bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY);
bpf_map_update_elem(&ongoing_client_connections, &goroutine_addr, &conn, BPF_ANY);
}
}

#ifndef NO_HEADER_PROPAGATION
Expand Down Expand Up @@ -775,7 +777,7 @@ int uprobe_netFdRead(struct pt_regs *ctx) {
bpf_dbg_printk("Found existing server connection, parsing FD information for socket tuples, %llx", goroutine_addr);

void *fd_ptr = GO_PARAM1(ctx);
get_conn_info_from_fd(fd_ptr, conn);
get_conn_info_from_fd(fd_ptr, conn); // ok to not check the result, we leave it as 0

//dbg_print_http_connection_info(conn);
}
Expand Down Expand Up @@ -813,7 +815,7 @@ int uprobe_persistConnRoundTrip(struct pt_regs *ctx) {
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(conn_conn_ptr + rwc_conn_pos)); // find conn
if (conn_ptr) {
connection_info_t conn = {0};
get_conn_info(conn_ptr, &conn);
get_conn_info(conn_ptr, &conn); // initialized to 0, no need to check the result if we succeeded
u64 pid_tid = bpf_get_current_pid_tgid();
u32 pid = pid_from_pid_tgid(pid_tid);
tp_info_pid_t tp_p = {
Expand Down
5 changes: 4 additions & 1 deletion bpf/go_redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ int uprobe_redis_with_writer(struct pt_regs *ctx) {
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(tcp_conn_ptr + 8)); // find conn
bpf_dbg_printk("conn ptr %llx", conn_ptr);
if (conn_ptr) {
get_conn_info(conn_ptr, &req->conn);
u8 ok = get_conn_info(conn_ptr, &req->conn);
if (!ok) {
__builtin_memset(&req->conn, 0, sizeof(connection_info_t));
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion bpf/go_sarama.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ int uprobe_sarama_broker_write(struct pt_regs *ctx) {
bpf_probe_read(&conn_ptr, sizeof(conn_ptr), (void *)(tcp_conn_ptr + 8)); // find conn
bpf_dbg_printk("conn ptr %llx", conn_ptr);
if (conn_ptr) {
get_conn_info(conn_ptr, &req.conn);
u8 ok = get_conn_info(conn_ptr, &req.conn);
if (!ok) {
__builtin_memset(&req.conn, 0, sizeof(connection_info_t));
}
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions pkg/internal/ebpf/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/binary"
"io"
"log/slog"
"net"
"os"
"strings"
"time"
Expand Down Expand Up @@ -228,3 +229,23 @@ func cstr(chars []uint8) string {

return string(chars[:addrLen])
}

func (connInfo *BPFConnInfo) reqHostInfo() (source, target string) {
src := make(net.IP, net.IPv6len)
dst := make(net.IP, net.IPv6len)
copy(src, connInfo.S_addr[:])
copy(dst, connInfo.D_addr[:])

srcStr := src.String()
dstStr := dst.String()

if src.IsUnspecified() {
srcStr = ""
}

if dst.IsUnspecified() {
dstStr = ""
}

return srcStr, dstStr
}
13 changes: 2 additions & 11 deletions pkg/internal/ebpf/common/http2grpc_transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package ebpfcommon
import (
"bytes"
"encoding/binary"
"net"
"strconv"
"strings"
"unsafe"

"github.com/cilium/ebpf/ringbuf"
lru "github.com/hashicorp/golang-lru/v2"
Expand Down Expand Up @@ -260,15 +260,6 @@ func (event *BPFHTTP2Info) eventType(protocol Protocol) request.EventType {
return 0
}

func (event *BPFHTTP2Info) hostInfo() (source, target string) {
src := make(net.IP, net.IPv6len)
dst := make(net.IP, net.IPv6len)
copy(src, event.ConnInfo.S_addr[:])
copy(dst, event.ConnInfo.D_addr[:])

return src.String(), dst.String()
}

// nolint:cyclop
func http2FromBuffers(event *BPFHTTP2Info) (request.Span, bool, error) {
bLen := len(event.Data)
Expand Down Expand Up @@ -333,7 +324,7 @@ func http2FromBuffers(event *BPFHTTP2Info) (request.Span, bool, error) {
peer := ""
host := ""
if event.ConnInfo.S_port != 0 || event.ConnInfo.D_port != 0 {
source, target := event.hostInfo()
source, target := (*BPFConnInfo)(unsafe.Pointer(&event.ConnInfo)).reqHostInfo()
host = target
peer = source
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/internal/ebpf/common/httpfltr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"testing"
"unsafe"

"github.com/cilium/ebpf/ringbuf"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -41,7 +42,7 @@ func TestHostInfo(t *testing.T) {
},
}

source, target := event.hostInfo()
source, target := (*BPFConnInfo)(unsafe.Pointer(&event.ConnInfo)).reqHostInfo()

assert.Equal(t, "192.168.0.1", source)
assert.Equal(t, "8.8.8.8", target)
Expand All @@ -53,7 +54,7 @@ func TestHostInfo(t *testing.T) {
},
}

source, target = event.hostInfo()
source, target = (*BPFConnInfo)(unsafe.Pointer(&event.ConnInfo)).reqHostInfo()

assert.Equal(t, "100::ffff:c0a8:1", source)
assert.Equal(t, "100::ffff:808:808", target)
Expand All @@ -62,10 +63,10 @@ func TestHostInfo(t *testing.T) {
ConnInfo: bpfConnectionInfoT{},
}

source, target = event.hostInfo()
source, target = (*BPFConnInfo)(unsafe.Pointer(&event.ConnInfo)).reqHostInfo()

assert.Equal(t, "::", source)
assert.Equal(t, "::", target)
assert.Equal(t, "", source)
assert.Equal(t, "", target)
}

func TestCstr(t *testing.T) {
Expand Down
12 changes: 2 additions & 10 deletions pkg/internal/ebpf/common/httpfltr_transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"strconv"
"strings"
"unsafe"

"github.com/cilium/ebpf/ringbuf"
"go.opentelemetry.io/otel/trace"
Expand Down Expand Up @@ -81,7 +82,7 @@ func HTTPInfoEventToSpan(event BPFHTTPInfo) (request.Span, bool, error) {
// When we can't find the connection info, we signal that through making the
// source and destination ports equal to max short. E.g. async SSL
if event.ConnInfo.S_port != 0 || event.ConnInfo.D_port != 0 {
source, target := event.hostInfo()
source, target := (*BPFConnInfo)(unsafe.Pointer(&event.ConnInfo)).reqHostInfo()
result.Host = target
result.Peer = source
} else {
Expand Down Expand Up @@ -168,15 +169,6 @@ func (event *BPFHTTPInfo) hostFromBuf() (string, int) {
return host, port
}

func (event *BPFHTTPInfo) hostInfo() (source, target string) {
src := make(net.IP, net.IPv6len)
dst := make(net.IP, net.IPv6len)
copy(src, event.ConnInfo.S_addr[:])
copy(dst, event.ConnInfo.D_addr[:])

return src.String(), dst.String()
}

func commName(pid uint32) string {
procPath := filepath.Join("/proc", strconv.FormatUint(uint64(pid), 10), "comm")
_, err := os.Stat(procPath)
Expand Down
14 changes: 3 additions & 11 deletions pkg/internal/ebpf/common/spanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package ebpfcommon
import (
"bytes"
"log/slog"
"net"
"unsafe"

trace2 "go.opentelemetry.io/otel/trace"

Expand Down Expand Up @@ -31,7 +31,8 @@ func HTTPRequestTraceToSpan(trace *HTTPRequestTrace) request.Span {
hostPort := 0

if trace.Conn.S_port != 0 || trace.Conn.D_port != 0 {
peer, hostname = trace.hostInfo()
peer, hostname = (*BPFConnInfo)(unsafe.Pointer(&trace.Conn)).reqHostInfo()

hostPort = int(trace.Conn.D_port)
}

Expand Down Expand Up @@ -60,15 +61,6 @@ func HTTPRequestTraceToSpan(trace *HTTPRequestTrace) request.Span {
}
}

func (trace *HTTPRequestTrace) hostInfo() (source, target string) {
src := make(net.IP, net.IPv6len)
dst := make(net.IP, net.IPv6len)
copy(src, trace.Conn.S_addr[:])
copy(dst, trace.Conn.D_addr[:])

return src.String(), dst.String()
}

func SQLRequestTraceToSpan(trace *SQLRequestTrace) request.Span {
if request.EventType(trace.Type) != request.EventTypeSQLClient {
log.Warn("unknown trace type", "type", trace.Type)
Expand Down
9 changes: 9 additions & 0 deletions pkg/internal/ebpf/common/spanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ebpfcommon

import (
"testing"
"unsafe"

"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -114,3 +115,11 @@ func TestSpanNesting(t *testing.T) {
b = makeSpanWithTimings(10000, 30000, 30000)
assert.False(t, (&a).Inside(&b))
}

func Test_EmptyHostInfo(t *testing.T) {
tr := HTTPRequestTrace{}
src, dest := (*BPFConnInfo)(unsafe.Pointer(&tr.Conn)).reqHostInfo()

assert.Equal(t, src, "")
assert.Equal(t, dest, "")
}
10 changes: 0 additions & 10 deletions pkg/internal/ebpf/common/tcp_detect_transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package ebpfcommon
import (
"bytes"
"encoding/binary"
"net"

"github.com/cilium/ebpf/ringbuf"

Expand Down Expand Up @@ -76,15 +75,6 @@ func ReadTCPRequestIntoSpan(record *ringbuf.Record, filter ServiceFilter) (reque
return request.Span{}, true, nil // ignore if we couldn't parse it
}

func (connInfo *BPFConnInfo) reqHostInfo() (source, target string) {
src := make(net.IP, net.IPv6len)
dst := make(net.IP, net.IPv6len)
copy(src, connInfo.S_addr[:])
copy(dst, connInfo.D_addr[:])

return src.String(), dst.String()
}

func reverseTCPEvent(trace *TCPRequestInfo) {
if trace.Direction == 0 {
trace.Direction = 1
Expand Down
Binary file modified pkg/internal/ebpf/goredis/bpf_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/goredis/bpf_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/goredis/bpf_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/goredis/bpf_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_tp_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_tp_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_tp_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/grpc/bpf_tp_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/kafkago/bpf_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/kafkago/bpf_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/kafkago/bpf_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/kafkago/bpf_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/sarama/bpf_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/sarama/bpf_bpfel_x86.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/sarama/bpf_debug_bpfel_arm64.o
Binary file not shown.
Binary file modified pkg/internal/ebpf/sarama/bpf_debug_bpfel_x86.o
Binary file not shown.
Loading