mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-09-25 04:17:25 +00:00
Fix Go crypto/tls
eBPF tracer on ARM64 (#1162)
* Handle the Go `ABIInternal` differences on ARM64 * Log the Capstone version, arch and mode * Upgrade Capstone from `4.0.2` to `5.0-rc2` to have ARM64 instructions fix * Use the correct register on ARM64 for reading buffer length * Fix the addresses on ARM64 * #run_acceptance_tests * Update `x86.o` * Update `arm64.o` * #run_acceptance_tests
This commit is contained in:
@@ -60,7 +60,18 @@ Capstone Engine: https://www.capstone-engine.org/
|
||||
|
||||
static __always_inline __u32 go_crypto_tls_get_fd_from_tcp_conn(struct pt_regs *ctx) {
|
||||
struct go_interface conn;
|
||||
long err = bpf_probe_read(&conn, sizeof(conn), (void*)GO_ABI_INTERNAL_PT_REGS_R1(ctx));
|
||||
long err;
|
||||
__u64 addr;
|
||||
#if defined(bpf_target_arm64)
|
||||
err = bpf_probe_read(&addr, sizeof(addr), (void*)GO_ABI_INTERNAL_PT_REGS_SP(ctx)+0x8);
|
||||
if (err != 0) {
|
||||
return invalid_fd;
|
||||
}
|
||||
#else
|
||||
addr = GO_ABI_INTERNAL_PT_REGS_R1(ctx);
|
||||
#endif
|
||||
|
||||
err = bpf_probe_read(&conn, sizeof(conn), (void*)addr);
|
||||
if (err != 0) {
|
||||
return invalid_fd;
|
||||
}
|
||||
@@ -88,14 +99,23 @@ static __always_inline void go_crypto_tls_uprobe(struct pt_regs *ctx, struct bpf
|
||||
}
|
||||
|
||||
struct ssl_info info = new_ssl_info();
|
||||
long err;
|
||||
|
||||
#if defined(bpf_target_arm64)
|
||||
err = bpf_probe_read(&info.buffer_len, sizeof(__u32), (void*)GO_ABI_INTERNAL_PT_REGS_SP(ctx)+0x18);
|
||||
if (err != 0) {
|
||||
log_error(ctx, LOG_ERROR_READING_BYTES_COUNT, pid_tgid, err, ORIGIN_SSL_UPROBE_CODE);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R2(ctx);
|
||||
#endif
|
||||
info.buffer = (void*)GO_ABI_INTERNAL_PT_REGS_R4(ctx);
|
||||
info.fd = go_crypto_tls_get_fd_from_tcp_conn(ctx);
|
||||
|
||||
// GO_ABI_INTERNAL_PT_REGS_GP is Goroutine address
|
||||
__u64 pid_fp = pid << 32 | GO_ABI_INTERNAL_PT_REGS_GP(ctx);
|
||||
long err = bpf_map_update_elem(go_context, &pid_fp, &info, BPF_ANY);
|
||||
err = bpf_map_update_elem(go_context, &pid_fp, &info, BPF_ANY);
|
||||
|
||||
if (err != 0) {
|
||||
log_error(ctx, LOG_ERROR_PUTTING_SSL_CONTEXT, pid_tgid, err, 0l);
|
||||
@@ -130,7 +150,15 @@ static __always_inline void go_crypto_tls_ex_uprobe(struct pt_regs *ctx, struct
|
||||
|
||||
// In case of read, the length is determined on return
|
||||
if (flags == FLAGS_IS_READ_BIT) {
|
||||
#if defined(bpf_target_arm64)
|
||||
// On ARM64 we look at a general-purpose register as an indicator of error return
|
||||
if (GO_ABI_INTERNAL_PT_REGS_R6(ctx) == 0x10) {
|
||||
return;
|
||||
}
|
||||
info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R7(ctx); // n in return n, nil
|
||||
#else
|
||||
info.buffer_len = GO_ABI_INTERNAL_PT_REGS_R1(ctx); // n in return n, nil
|
||||
#endif
|
||||
// This check achieves ignoring 0 length reads (the reads result with an error)
|
||||
if (info.buffer_len <= 0) {
|
||||
return;
|
||||
|
@@ -66,11 +66,12 @@ https://go.googlesource.com/go/+/refs/heads/dev.regabi/src/cmd/compile/internal-
|
||||
https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/AMD64Ops.go#L100
|
||||
*/
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R1(x) ((x)->eax)
|
||||
#define GO_ABI_INTERNAL_PT_REGS_P2(x) ((x)->ecx)
|
||||
#define GO_ABI_INTERNAL_PT_REGS_P3(x) ((x)->edx)
|
||||
#define GO_ABI_INTERNAL_PT_REGS_P4(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_P5(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_P6(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R2(x) ((x)->ecx)
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R3(x) ((x)->edx)
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R4(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R5(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R6(x) 0
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R7(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)
|
||||
@@ -83,6 +84,7 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/AMD6
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R4(x) ((x)->rbx)
|
||||
#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_R7(x) ((x)->rdi)
|
||||
#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)
|
||||
@@ -101,7 +103,8 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/ARM6
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R4(x) ((x)->uregs[3])
|
||||
#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_R7(x) ((x)->uregs[6])
|
||||
#define GO_ABI_INTERNAL_PT_REGS_SP(x) ((x)->uregs[13])
|
||||
#define GO_ABI_INTERNAL_PT_REGS_FP(x) ((x)->uregs[29])
|
||||
#define GO_ABI_INTERNAL_PT_REGS_GP(x) ((x)->uregs[28])
|
||||
|
||||
@@ -116,7 +119,8 @@ struct pt_regs;
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R4(x) (((PT_REGS_ARM64 *)(x))->regs[3])
|
||||
#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_R7(x) (((PT_REGS_ARM64 *)(x))->regs[6])
|
||||
#define GO_ABI_INTERNAL_PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
|
||||
#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])
|
||||
|
||||
@@ -132,6 +136,7 @@ https://github.com/golang/go/blob/go1.17.6/src/cmd/compile/internal/ssa/gen/PPC6
|
||||
#define GO_ABI_INTERNAL_PT_REGS_R4(x) ((x)->gpr[6])
|
||||
#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_R7(x) ((x)->gpr[9])
|
||||
#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])
|
||||
|
@@ -77,7 +77,7 @@ func getOffsets(filePath string) (offsets map[string]*goExtendedOffset, err erro
|
||||
case "arm64":
|
||||
engine, err = gapstone.New(
|
||||
gapstone.CS_ARCH_ARM64,
|
||||
gapstone.CS_MODE_ARM,
|
||||
gapstone.CS_MODE_LITTLE_ENDIAN,
|
||||
)
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported architecture: %v", runtime.GOARCH)
|
||||
@@ -86,6 +86,16 @@ func getOffsets(filePath string) (offsets map[string]*goExtendedOffset, err erro
|
||||
return
|
||||
}
|
||||
|
||||
engineMajor, engineMinor := engine.Version()
|
||||
logger.Log.Infof(
|
||||
"Disassembling %s with Capstone %d.%d (arch: %d, mode: %d)",
|
||||
filePath,
|
||||
engineMajor,
|
||||
engineMinor,
|
||||
engine.Arch(),
|
||||
engine.Mode(),
|
||||
)
|
||||
|
||||
offsets = make(map[string]*goExtendedOffset)
|
||||
var fd *os.File
|
||||
fd, err = os.Open(filePath)
|
||||
@@ -133,7 +143,7 @@ func getOffsets(filePath string) (offsets map[string]*goExtendedOffset, err erro
|
||||
extendedOffset := &goExtendedOffset{enter: offset}
|
||||
|
||||
// source: https://gist.github.com/grantseltzer/3efa8ecc5de1fb566e8091533050d608
|
||||
// skip over any symbols that aren't functinons/methods
|
||||
// skip over any symbols that aren't functions/methods
|
||||
if sym.Info != byte(2) && sym.Info != byte(18) {
|
||||
offsets[sym.Name] = extendedOffset
|
||||
continue
|
||||
|
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user