From 590fa08c810c60a77cf08eb5ea5ddeb42150499f Mon Sep 17 00:00:00 2001 From: David Levanon Date: Mon, 28 Mar 2022 14:19:06 +0300 Subject: [PATCH] EBPF error handling --- tap/passive_tapper.go | 6 +- tap/tlstapper/bpf/fd_to_address_tracepoints.c | 32 +++-- tap/tlstapper/bpf/fd_tracepoints.c | 16 +-- tap/tlstapper/bpf/include/log.h | 79 ++++++++++++ tap/tlstapper/bpf/include/logger_messages.h | 42 +++++++ tap/tlstapper/bpf/include/maps.h | 1 + tap/tlstapper/bpf/openssl_uprobes.c | 49 ++++---- tap/tlstapper/bpf/tls_tapper.c | 2 + tap/tlstapper/bpf_logger.go | 116 ++++++++++++++++++ tap/tlstapper/bpf_logger_messages.go | 25 ++++ tap/tlstapper/tls_tapper.go | 31 ++++- tap/tlstapper/tlstapper_bpfeb.go | 3 + tap/tlstapper/tlstapper_bpfeb.o | Bin 66824 -> 116712 bytes tap/tlstapper/tlstapper_bpfel.go | 3 + tap/tlstapper/tlstapper_bpfel.o | Bin 66824 -> 116712 bytes 15 files changed, 342 insertions(+), 63 deletions(-) create mode 100644 tap/tlstapper/bpf/include/log.h create mode 100644 tap/tlstapper/bpf/include/logger_messages.h create mode 100644 tap/tlstapper/bpf_logger.go create mode 100644 tap/tlstapper/bpf_logger_messages.go diff --git a/tap/passive_tapper.go b/tap/passive_tapper.go index e9ecf5216..161b976b4 100644 --- a/tap/passive_tapper.go +++ b/tap/passive_tapper.go @@ -259,9 +259,10 @@ func startPassiveTapper(streamsMap *tcpStreamMap, assembler *tcpAssembler) { func startTlsTapper(extension *api.Extension, outputItems chan *api.OutputChannelItem, options *api.TrafficFilteringOptions) *tlstapper.TlsTapper { tls := tlstapper.TlsTapper{} - tlsPerfBufferSize := os.Getpagesize() * 100 + chunksBufferSize := os.Getpagesize() * 100 + logBufferSize := os.Getpagesize() - if err := tls.Init(tlsPerfBufferSize, *procfs, extension); err != nil { + if err := tls.Init(chunksBufferSize, logBufferSize, *procfs, extension); err != nil { tlstapper.LogError(err) return nil } @@ -285,6 +286,7 @@ func startTlsTapper(extension *api.Extension, outputItems chan *api.OutputChanne OutputChannel: outputItems, } + go tls.PollForLogging() go tls.Poll(emitter, options) return &tls diff --git a/tap/tlstapper/bpf/fd_to_address_tracepoints.c b/tap/tlstapper/bpf/fd_to_address_tracepoints.c index 12effa18d..d00dfc1a2 100644 --- a/tap/tlstapper/bpf/fd_to_address_tracepoints.c +++ b/tap/tlstapper/bpf/fd_to_address_tracepoints.c @@ -7,8 +7,12 @@ Copyright (C) UP9 Inc. #include "include/headers.h" #include "include/util.h" #include "include/maps.h" +#include "include/log.h" +#include "include/logger_messages.h" #include "include/pids.h" +#define IPV4_ADDR_LEN (16) + struct accept_info { __u64* sockaddr; __u32* addrlen; @@ -41,9 +45,7 @@ void sys_enter_accept4(struct sys_enter_accept4_ctx *ctx) { long err = bpf_map_update_elem(&accept_syscall_context, &id, &info, BPF_ANY); if (err != 0) { - char msg[] = "Error putting accept info (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_ACCEPT_INFO, id, err, 0l); } } @@ -70,6 +72,7 @@ void sys_exit_accept4(struct sys_exit_accept4_ctx *ctx) { struct accept_info *infoPtr = bpf_map_lookup_elem(&accept_syscall_context, &id); if (infoPtr == NULL) { + log_error(ctx, LOG_ERROR_GETTING_ACCEPT_INFO, id, 0l, 0l); return; } @@ -79,15 +82,14 @@ void sys_exit_accept4(struct sys_exit_accept4_ctx *ctx) { bpf_map_delete_elem(&accept_syscall_context, &id); if (err != 0) { - char msg[] = "Error reading accept info from accept syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_ACCEPT_INFO, id, err, 0l); return; } __u32 addrlen; bpf_probe_read(&addrlen, sizeof(__u32), info.addrlen); - if (addrlen != 16) { + if (addrlen != IPV4_ADDR_LEN) { // Currently only ipv4 is supported linux-src/include/linux/inet.h return; } @@ -105,9 +107,7 @@ void sys_exit_accept4(struct sys_exit_accept4_ctx *ctx) { err = bpf_map_update_elem(&file_descriptor_to_ipv4, &key, &fdinfo, BPF_ANY); if (err != 0) { - char msg[] = "Error putting fd to address mapping from accept (key: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), key, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_FD_MAPPING, id, err, ORIGIN_SYS_EXIT_ACCEPT4_CODE); } } @@ -145,9 +145,7 @@ void sys_enter_connect(struct sys_enter_connect_ctx *ctx) { long err = bpf_map_update_elem(&connect_syscall_info, &id, &info, BPF_ANY); if (err != 0) { - char msg[] = "Error putting connect info (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_CONNECT_INFO, id, err, 0l); } } @@ -176,6 +174,7 @@ void sys_exit_connect(struct sys_exit_connect_ctx *ctx) { struct connect_info *infoPtr = bpf_map_lookup_elem(&connect_syscall_info, &id); if (infoPtr == NULL) { + log_error(ctx, LOG_ERROR_GETTING_CONNECT_INFO, id, 0l, 0l); return; } @@ -185,12 +184,11 @@ void sys_exit_connect(struct sys_exit_connect_ctx *ctx) { bpf_map_delete_elem(&connect_syscall_info, &id); if (err != 0) { - char msg[] = "Error reading connect info from connect syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_CONNECT_INFO, id, err, 0l); return; } - if (info.addrlen != 16) { + if (info.addrlen != IPV4_ADDR_LEN) { // Currently only ipv4 is supported linux-src/include/linux/inet.h return; } @@ -208,8 +206,6 @@ void sys_exit_connect(struct sys_exit_connect_ctx *ctx) { err = bpf_map_update_elem(&file_descriptor_to_ipv4, &key, &fdinfo, BPF_ANY); if (err != 0) { - char msg[] = "Error putting fd to address mapping from connect (key: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), key, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_FD_MAPPING, id, err, ORIGIN_SYS_EXIT_CONNECT_CODE); } } diff --git a/tap/tlstapper/bpf/fd_tracepoints.c b/tap/tlstapper/bpf/fd_tracepoints.c index 345d258f3..88add7f44 100644 --- a/tap/tlstapper/bpf/fd_tracepoints.c +++ b/tap/tlstapper/bpf/fd_tracepoints.c @@ -7,6 +7,8 @@ Copyright (C) UP9 Inc. #include "include/headers.h" #include "include/util.h" #include "include/maps.h" +#include "include/log.h" +#include "include/logger_messages.h" #include "include/pids.h" struct sys_enter_read_ctx { @@ -36,8 +38,7 @@ void sys_enter_read(struct sys_enter_read_ctx *ctx) { long err = bpf_probe_read(&info, sizeof(struct ssl_info), infoPtr); if (err != 0) { - char msg[] = "Error reading read info from read syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_SSL_CONTEXT, id, err, ORIGIN_SYS_ENTER_READ_CODE); return; } @@ -46,9 +47,7 @@ void sys_enter_read(struct sys_enter_read_ctx *ctx) { err = bpf_map_update_elem(&ssl_read_context, &id, &info, BPF_ANY); if (err != 0) { - char msg[] = "Error putting file descriptor from read syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_FILE_DESCRIPTOR, id, err, ORIGIN_SYS_ENTER_READ_CODE); } } @@ -79,8 +78,7 @@ void sys_enter_write(struct sys_enter_write_ctx *ctx) { long err = bpf_probe_read(&info, sizeof(struct ssl_info), infoPtr); if (err != 0) { - char msg[] = "Error reading write context from write syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_SSL_CONTEXT, id, err, ORIGIN_SYS_ENTER_WRITE_CODE); return; } @@ -89,8 +87,6 @@ void sys_enter_write(struct sys_enter_write_ctx *ctx) { err = bpf_map_update_elem(&ssl_write_context, &id, &info, BPF_ANY); if (err != 0) { - char msg[] = "Error putting file descriptor from write syscall (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); - return; + log_error(ctx, LOG_ERROR_PUTTING_FILE_DESCRIPTOR, id, err, ORIGIN_SYS_ENTER_WRITE_CODE); } } diff --git a/tap/tlstapper/bpf/include/log.h b/tap/tlstapper/bpf/include/log.h new file mode 100644 index 000000000..9d501024e --- /dev/null +++ b/tap/tlstapper/bpf/include/log.h @@ -0,0 +1,79 @@ +/* +Note: This file is licenced differently from the rest of the project +SPDX-License-Identifier: GPL-2.0 +Copyright (C) UP9 Inc. +*/ + +#ifndef __LOG__ +#define __LOG__ + +// The same consts defined in bpf_logger.go +// +#define LOG_LEVEL_ERROR (0) +#define LOG_LEVEL_INFO (1) +#define LOG_LEVEL_DEBUG (2) + +// The same struct can be found in bpf_logger.go +// +// Be careful when editing, alignment and padding should be exactly the same in go/c. +// +struct log_message { + __u32 level; + __u32 message_code; + __u64 arg1; + __u64 arg2; + __u64 arg3; +}; + +static __always_inline void log_error(void* ctx, __u16 message_code, __u64 arg1, __u64 arg2, __u64 arg3) { + struct log_message entry = {}; + + entry.level = LOG_LEVEL_ERROR; + entry.message_code = message_code; + entry.arg1 = arg1; + entry.arg2 = arg2; + entry.arg3 = arg3; + + long err = bpf_perf_event_output(ctx, &log_buffer, BPF_F_CURRENT_CPU, &entry, sizeof(struct log_message)); + + if (err != 0) { + char msg[] = "Error writing log error to perf buffer - %ld"; + bpf_trace_printk(msg, sizeof(msg), err); + } +} + +static __always_inline void log_info(void* ctx, __u16 message_code, __u64 arg1, __u64 arg2, __u64 arg3) { + struct log_message entry = {}; + + entry.level = LOG_LEVEL_INFO; + entry.message_code = message_code; + entry.arg1 = arg1; + entry.arg2 = arg2; + entry.arg3 = arg3; + + long err = bpf_perf_event_output(ctx, &log_buffer, BPF_F_CURRENT_CPU, &entry, sizeof(struct log_message)); + + if (err != 0) { + char msg[] = "Error writing log info to perf buffer - %ld"; + bpf_trace_printk(msg, sizeof(msg), arg1, err); + } +} + +static __always_inline void log_debug(void* ctx, __u16 message_code, __u64 arg1, __u64 arg2, __u64 arg3) { + struct log_message entry = {}; + + entry.level = LOG_LEVEL_DEBUG; + entry.message_code = message_code; + entry.arg1 = arg1; + entry.arg2 = arg2; + entry.arg3 = arg3; + + long err = bpf_perf_event_output(ctx, &log_buffer, BPF_F_CURRENT_CPU, &entry, sizeof(struct log_message)); + + if (err != 0) { + char msg[] = "Error writing log debug to perf buffer - %ld"; + bpf_trace_printk(msg, sizeof(msg), arg1, err); + } +} + +#endif /* __LOG__ */ diff --git a/tap/tlstapper/bpf/include/logger_messages.h b/tap/tlstapper/bpf/include/logger_messages.h new file mode 100644 index 000000000..69954f43a --- /dev/null +++ b/tap/tlstapper/bpf/include/logger_messages.h @@ -0,0 +1,42 @@ +/* +Note: This file is licenced differently from the rest of the project +SPDX-License-Identifier: GPL-2.0 +Copyright (C) UP9 Inc. +*/ + +#ifndef __LOG_MESSAGES__ +#define __LOG_MESSAGES__ + +// Must be synced with bpf_logger_messages.go +// +#define LOG_ERROR_READING_BYTES_COUNT (0) +#define LOG_ERROR_READING_FD_ADDRESS (1) +#define LOG_ERROR_READING_FROM_SSL_BUFFER (2) +#define LOG_ERROR_BUFFER_TOO_BIG (3) +#define LOG_ERROR_ALLOCATING_CHUNK (4) +#define LOG_ERROR_READING_SSL_CONTEXT (5) +#define LOG_ERROR_PUTTING_SSL_CONTEXT (6) +#define LOG_ERROR_GETTING_SSL_CONTEXT (7) +#define LOG_ERROR_MISSING_FILE_DESCRIPTOR (8) +#define LOG_ERROR_PUTTING_FILE_DESCRIPTOR (9) +#define LOG_ERROR_PUTTING_ACCEPT_INFO (10) +#define LOG_ERROR_GETTING_ACCEPT_INFO (11) +#define LOG_ERROR_READING_ACCEPT_INFO (12) +#define LOG_ERROR_PUTTING_FD_MAPPING (13) +#define LOG_ERROR_PUTTING_CONNECT_INFO (14) +#define LOG_ERROR_GETTING_CONNECT_INFO (15) +#define LOG_ERROR_READING_CONNECT_INFO (16) + +// Sometimes we have the same error, happening from different locations. +// in order to be able to distinct between them in the log, we add an +// extra number that identify the location. The number can be anything, +// but do not give the same number to different origins. +// +#define ORIGIN_SSL_UPROBE_CODE (0l) +#define ORIGIN_SSL_URETPROBE_CODE (1l) +#define ORIGIN_SYS_ENTER_READ_CODE (2l) +#define ORIGIN_SYS_ENTER_WRITE_CODE (3l) +#define ORIGIN_SYS_EXIT_ACCEPT4_CODE (4l) +#define ORIGIN_SYS_EXIT_CONNECT_CODE (5l) + +#endif /* __LOG_MESSAGES__ */ diff --git a/tap/tlstapper/bpf/include/maps.h b/tap/tlstapper/bpf/include/maps.h index 1110f5ca0..dad1ca59d 100644 --- a/tap/tlstapper/bpf/include/maps.h +++ b/tap/tlstapper/bpf/include/maps.h @@ -70,5 +70,6 @@ BPF_LRU_HASH(ssl_write_context, __u64, struct ssl_info); BPF_LRU_HASH(ssl_read_context, __u64, struct ssl_info); BPF_HASH(file_descriptor_to_ipv4, __u64, struct fd_info); BPF_PERF_OUTPUT(chunks_buffer); +BPF_PERF_OUTPUT(log_buffer); #endif /* __MAPS__ */ diff --git a/tap/tlstapper/bpf/openssl_uprobes.c b/tap/tlstapper/bpf/openssl_uprobes.c index e449dd114..a80107511 100644 --- a/tap/tlstapper/bpf/openssl_uprobes.c +++ b/tap/tlstapper/bpf/openssl_uprobes.c @@ -7,6 +7,8 @@ Copyright (C) UP9 Inc. #include "include/headers.h" #include "include/util.h" #include "include/maps.h" +#include "include/log.h" +#include "include/logger_messages.h" #include "include/pids.h" // Heap-like area for eBPF programs - stack size limited to 512 bytes, we must use maps for bigger (chunk) objects. @@ -39,15 +41,14 @@ static __always_inline int get_count_bytes(struct pt_regs *ctx, struct ssl_info* long err = bpf_probe_read(&countBytes, sizeof(size_t), (void*) info->count_ptr); if (err != 0) { - char msg[] = "Error reading bytes count of _ex (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_BYTES_COUNT, id, err, 0l); return 0; } return countBytes; } -static __always_inline void add_address_to_chunk(struct tlsChunk* chunk, __u64 id, __u32 fd) { +static __always_inline void add_address_to_chunk(struct pt_regs *ctx, struct tlsChunk* chunk, __u64 id, __u32 fd) { __u32 pid = id >> 32; __u64 key = (__u64) pid << 32 | fd; @@ -61,8 +62,7 @@ static __always_inline void add_address_to_chunk(struct tlsChunk* chunk, __u64 i chunk->flags |= (fdinfo->flags & FLAGS_IS_CLIENT_BIT); if (err != 0) { - char msg[] = "Error reading from fd address %ld - %ld"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_FD_ADDRESS, id, err, 0l); } } @@ -88,8 +88,7 @@ static __always_inline void send_chunk_part(struct pt_regs *ctx, __u8* buffer, _ } if (err != 0) { - char msg[] = "Error reading from ssl buffer %ld - %ld"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_FROM_SSL_BUFFER, id, err, 0l); return; } @@ -101,8 +100,9 @@ static __always_inline void send_chunk(struct pt_regs *ctx, __u8* buffer, __u64 // // https://lwn.net/Articles/794934/ // - // If we want to compile in kernel older than 5.3, we should add "#pragma unroll" to this loop + // However we want to run in kernel older than 5.3, hence we use "#pragma unroll" anyway // + #pragma unroll for (int i = 0; i < MAX_CHUNKS_PER_OPERATION; i++) { if (chunk->len <= (CHUNK_SIZE * i)) { break; @@ -120,8 +120,7 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf } if (countBytes > (CHUNK_SIZE * MAX_CHUNKS_PER_OPERATION)) { - char msg[] = "Buffer too big %d (id: %ld)"; - bpf_trace_printk(msg, sizeof(msg), countBytes, id); + log_error(ctx, LOG_ERROR_BUFFER_TOO_BIG, id, countBytes, 0l); return; } @@ -134,8 +133,7 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf chunk = bpf_map_lookup_elem(&heap, &zero); if (!chunk) { - char msg[] = "Unable to allocate chunk (id: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id); + log_error(ctx, LOG_ERROR_ALLOCATING_CHUNK, id, 0l, 0l); return; } @@ -145,11 +143,11 @@ static __always_inline void output_ssl_chunk(struct pt_regs *ctx, struct ssl_inf chunk->len = countBytes; chunk->fd = info->fd; - add_address_to_chunk(chunk, id, chunk->fd); + add_address_to_chunk(ctx, chunk, id, chunk->fd); send_chunk(ctx, info->buffer, id, chunk); } -static __always_inline void ssl_uprobe(void* ssl, void* buffer, int num, struct bpf_map_def* map_fd, size_t *count_ptr) { +static __always_inline void ssl_uprobe(struct pt_regs *ctx, void* ssl, void* buffer, int num, struct bpf_map_def* map_fd, size_t *count_ptr) { __u64 id = bpf_get_current_pid_tgid(); if (!should_tap(id >> 32)) { @@ -166,8 +164,7 @@ static __always_inline void ssl_uprobe(void* ssl, void* buffer, int num, struct long err = bpf_probe_read(&info, sizeof(struct ssl_info), infoPtr); if (err != 0) { - char msg[] = "Error reading old ssl context (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_SSL_CONTEXT, id, err, ORIGIN_SSL_UPROBE_CODE); } if ((bpf_ktime_get_ns() - info.created_at_nano) > SSL_INFO_MAX_TTL_NANO) { @@ -184,8 +181,7 @@ static __always_inline void ssl_uprobe(void* ssl, void* buffer, int num, struct long err = bpf_map_update_elem(map_fd, &id, &info, BPF_ANY); if (err != 0) { - char msg[] = "Error putting ssl context (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_PUTTING_SSL_CONTEXT, id, err, 0l); } } @@ -199,8 +195,7 @@ static __always_inline void ssl_uretprobe(struct pt_regs *ctx, struct bpf_map_de struct ssl_info *infoPtr = bpf_map_lookup_elem(map_fd, &id); if (infoPtr == NULL) { - char msg[] = "Error getting ssl context info (id: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id); + log_error(ctx, LOG_ERROR_GETTING_SSL_CONTEXT, id, 0l, 0l); return; } @@ -220,14 +215,12 @@ static __always_inline void ssl_uretprobe(struct pt_regs *ctx, struct bpf_map_de // bpf_map_delete_elem(map_fd, &id); if (err != 0) { - char msg[] = "Error reading ssl context (id: %ld) (err: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id, err); + log_error(ctx, LOG_ERROR_READING_SSL_CONTEXT, id, err, ORIGIN_SSL_URETPROBE_CODE); return; } if (info.fd == -1) { - char msg[] = "File descriptor is missing from ssl info (id: %ld)"; - bpf_trace_printk(msg, sizeof(msg), id); + log_error(ctx, LOG_ERROR_MISSING_FILE_DESCRIPTOR, id, 0l, 0l); return; } @@ -236,7 +229,7 @@ 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(ssl, buffer, num, &ssl_write_context, 0); + ssl_uprobe(ctx, ssl, buffer, num, &ssl_write_context, 0); } SEC("uretprobe/ssl_write") @@ -246,7 +239,7 @@ void BPF_KPROBE(ssl_ret_write) { SEC("uprobe/ssl_read") void BPF_KPROBE(ssl_read, void* ssl, void* buffer, int num) { - ssl_uprobe(ssl, buffer, num, &ssl_read_context, 0); + ssl_uprobe(ctx, ssl, buffer, num, &ssl_read_context, 0); } SEC("uretprobe/ssl_read") @@ -256,7 +249,7 @@ void BPF_KPROBE(ssl_ret_read) { SEC("uprobe/ssl_write_ex") void BPF_KPROBE(ssl_write_ex, void* ssl, void* buffer, size_t num, size_t *written) { - ssl_uprobe(ssl, buffer, num, &ssl_write_context, written); + ssl_uprobe(ctx, ssl, buffer, num, &ssl_write_context, written); } SEC("uretprobe/ssl_write_ex") @@ -266,7 +259,7 @@ void BPF_KPROBE(ssl_ret_write_ex) { SEC("uprobe/ssl_read_ex") void BPF_KPROBE(ssl_read_ex, void* ssl, void* buffer, size_t num, size_t *readbytes) { - ssl_uprobe(ssl, buffer, num, &ssl_read_context, readbytes); + ssl_uprobe(ctx, ssl, buffer, num, &ssl_read_context, readbytes); } SEC("uretprobe/ssl_read_ex") diff --git a/tap/tlstapper/bpf/tls_tapper.c b/tap/tlstapper/bpf/tls_tapper.c index f48fec6fb..9878ef690 100644 --- a/tap/tlstapper/bpf/tls_tapper.c +++ b/tap/tlstapper/bpf/tls_tapper.c @@ -7,6 +7,8 @@ Copyright (C) UP9 Inc. #include "include/headers.h" #include "include/util.h" #include "include/maps.h" +#include "include/log.h" +#include "include/logger_messages.h" #include "include/pids.h" // To avoid multiple .o files diff --git a/tap/tlstapper/bpf_logger.go b/tap/tlstapper/bpf_logger.go new file mode 100644 index 000000000..ec794e66f --- /dev/null +++ b/tap/tlstapper/bpf_logger.go @@ -0,0 +1,116 @@ +package tlstapper + +import ( + "bytes" + "encoding/binary" + "strings" + + "github.com/cilium/ebpf/perf" + "github.com/go-errors/errors" + "github.com/up9inc/mizu/shared/logger" +) + +const logPrefix = "[bpf] " + +// The same consts defined in log.h +// +const logLevelError = 0 +const logLevelInfo = 1 +const logLevelDebug = 2 + +type logMessage struct { + Level uint32 + MessageCode uint32 + Arg1 uint64 + Arg2 uint64 + Arg3 uint64 +} + +type bpfLogger struct { + logReader *perf.Reader +} + +func newBpfLogger() *bpfLogger { + return &bpfLogger{ + logReader: nil, + } +} + +func (p *bpfLogger) init(bpfObjects *tlsTapperObjects, bufferSize int) error { + var err error + + p.logReader, err = perf.NewReader(bpfObjects.LogBuffer, bufferSize) + + if err != nil { + return errors.Wrap(err, 0) + } + + return nil +} + +func (p *bpfLogger) close() error { + return p.logReader.Close() +} + +func (p *bpfLogger) poll() { + logger.Log.Infof("Start polling for bpf logs") + + for { + record, err := p.logReader.Read() + + if err != nil { + if errors.Is(err, perf.ErrClosed) { + return + } + + LogError(errors.Errorf("Error reading from bpf logger perf buffer, aboring logger! %w", err)) + return + } + + if record.LostSamples != 0 { + logger.Log.Infof("Log buffer is full, dropped %d logs", record.LostSamples) + continue + } + + buffer := bytes.NewReader(record.RawSample) + + var log logMessage + + if err := binary.Read(buffer, binary.LittleEndian, &log); err != nil { + LogError(errors.Errorf("Error parsing log %v", err)) + continue + } + + p.log(&log) + } +} + +func (p *bpfLogger) log(log *logMessage) { + if int(log.MessageCode) >= len(bpfLogMessages) { + logger.Log.Errorf("Unknown message code from bpf logger %d", log.MessageCode) + return + } + + format := bpfLogMessages[log.MessageCode] + tokensCount := strings.Count(format, "%") + + if tokensCount == 0 { + p.logLevel(log.Level, format) + } else if tokensCount == 1 { + p.logLevel(log.Level, format, log.Arg1) + } else if tokensCount == 2 { + p.logLevel(log.Level, format, log.Arg1, log.Arg2) + } else if tokensCount == 3 { + p.logLevel(log.Level, format, log.Arg1, log.Arg2, log.Arg3) + } +} + +func (p *bpfLogger) logLevel(level uint32, format string, args ...interface{}) { + if level == logLevelError { + logger.Log.Errorf(logPrefix+format, args...) + } else if level == logLevelInfo { + logger.Log.Infof(logPrefix+format, args...) + } else if level == logLevelDebug { + logger.Log.Debugf(logPrefix+format, args...) + } +} diff --git a/tap/tlstapper/bpf_logger_messages.go b/tap/tlstapper/bpf_logger_messages.go new file mode 100644 index 000000000..bfcf84138 --- /dev/null +++ b/tap/tlstapper/bpf_logger_messages.go @@ -0,0 +1,25 @@ +package tlstapper + +// Must be synced with logger_messages.h +// +var bpfLogMessages = []string { + /*0000*/ "[%d] Unable to read bytes count from _ex methods [err: %d]", + /*0001*/ "[%d] Unable to read ipv4 address [err: %d]", + /*0002*/ "[%d] Unable to read ssl buffer [err: %d]", + /*0003*/ "[%d] Buffer is too big [size: %d]", + /*0004*/ "[%d] Unable to allocate chunk in bpf heap", + /*0005*/ "[%d] Unable to read ssl context [err: %d] [origin: %d]", + /*0006*/ "[%d] Unable to put ssl context [err: %d]", + /*0007*/ "[%d] Unable to get ssl context", + /*0008*/ "[%d] File descriptor is missing for tls chunk", + /*0009*/ "[%d] Unable to put file descriptor [err: %d] [origin: %d]", + /*0010*/ "[%d] Unable to put accept info [err: %d]", + /*0011*/ "[%d] Unable to get accept info", + /*0012*/ "[%d] Unable to read accept info [err: %d]", + /*0013*/ "[%d] Unable to put file descriptor to address mapping [err: %d] [origin: %d]", + /*0014*/ "[%d] Unable to put connect info [err: %d]", + /*0015*/ "[%d] Unable to get connect info", + /*0016*/ "[%d] Unable to read connect info [err: %d]", + +} + diff --git a/tap/tlstapper/tls_tapper.go b/tap/tlstapper/tls_tapper.go index 6886e147c..e3982bd66 100644 --- a/tap/tlstapper/tls_tapper.go +++ b/tap/tlstapper/tls_tapper.go @@ -8,6 +8,8 @@ import ( "sync" ) +const GLOABL_TAP_PID = 0 + //go:generate go run github.com/cilium/ebpf/cmd/bpf2go tlsTapper bpf/tls_tapper.c -- -O2 -g -D__TARGET_ARCH_x86 type TlsTapper struct { @@ -15,11 +17,12 @@ type TlsTapper struct { syscallHooks syscallHooks sslHooksStructs []sslHooks poller *tlsPoller + bpfLogger *bpfLogger registeredPids sync.Map } -func (t *TlsTapper) Init(bufferSize int, procfs string, extension *api.Extension) error { - logger.Log.Infof("Initializing tls tapper (bufferSize: %v)", bufferSize) +func (t *TlsTapper) Init(chunksBufferSize int, logBufferSize int, procfs string, extension *api.Extension) error { + logger.Log.Infof("Initializing tls tapper (chunksSize: %d) (logSize: %d)", chunksBufferSize, logBufferSize) if err := setupRLimit(); err != nil { return err @@ -37,16 +40,25 @@ func (t *TlsTapper) Init(bufferSize int, procfs string, extension *api.Extension t.sslHooksStructs = make([]sslHooks, 0) + t.bpfLogger = newBpfLogger() + if err := t.bpfLogger.init(&t.bpfObjects, logBufferSize); err != nil { + return err + } + t.poller = newTlsPoller(t, extension, procfs) - return t.poller.init(&t.bpfObjects, bufferSize) + return t.poller.init(&t.bpfObjects, chunksBufferSize) } func (t *TlsTapper) Poll(emitter api.Emitter, options *api.TrafficFilteringOptions) { t.poller.poll(emitter, options) } +func (t *TlsTapper) PollForLogging() { + t.bpfLogger.poll() +} + func (t *TlsTapper) GlobalTap(sslLibrary string) error { - return t.tapPid(0, sslLibrary) + return t.tapPid(GLOABL_TAP_PID, sslLibrary) } func (t *TlsTapper) AddPid(procfs string, pid uint32) error { @@ -74,7 +86,12 @@ func (t *TlsTapper) RemovePid(pid uint32) error { func (t *TlsTapper) ClearPids() { t.registeredPids.Range(func(key, v interface{}) bool { - if err := t.RemovePid(key.(uint32)); err != nil { + pid := key.(uint32) + if pid == GLOABL_TAP_PID { + return true + } + + if err := t.RemovePid(pid); err != nil { LogError(err) } t.registeredPids.Delete(key) @@ -95,6 +112,10 @@ func (t *TlsTapper) Close() []error { errors = append(errors, sslHooks.close()...) } + if err := t.bpfLogger.close(); err != nil { + errors = append(errors, err) + } + if err := t.poller.close(); err != nil { errors = append(errors, err) } diff --git a/tap/tlstapper/tlstapper_bpfeb.go b/tap/tlstapper/tlstapper_bpfeb.go index 03e880b08..a4b07d7f4 100644 --- a/tap/tlstapper/tlstapper_bpfeb.go +++ b/tap/tlstapper/tlstapper_bpfeb.go @@ -78,6 +78,7 @@ type tlsTapperMapSpecs struct { ConnectSyscallInfo *ebpf.MapSpec `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.MapSpec `ebpf:"file_descriptor_to_ipv4"` Heap *ebpf.MapSpec `ebpf:"heap"` + LogBuffer *ebpf.MapSpec `ebpf:"log_buffer"` PidsMap *ebpf.MapSpec `ebpf:"pids_map"` SslReadContext *ebpf.MapSpec `ebpf:"ssl_read_context"` SslWriteContext *ebpf.MapSpec `ebpf:"ssl_write_context"` @@ -107,6 +108,7 @@ type tlsTapperMaps struct { ConnectSyscallInfo *ebpf.Map `ebpf:"connect_syscall_info"` FileDescriptorToIpv4 *ebpf.Map `ebpf:"file_descriptor_to_ipv4"` Heap *ebpf.Map `ebpf:"heap"` + LogBuffer *ebpf.Map `ebpf:"log_buffer"` PidsMap *ebpf.Map `ebpf:"pids_map"` SslReadContext *ebpf.Map `ebpf:"ssl_read_context"` SslWriteContext *ebpf.Map `ebpf:"ssl_write_context"` @@ -119,6 +121,7 @@ func (m *tlsTapperMaps) Close() error { m.ConnectSyscallInfo, m.FileDescriptorToIpv4, m.Heap, + m.LogBuffer, m.PidsMap, m.SslReadContext, m.SslWriteContext, diff --git a/tap/tlstapper/tlstapper_bpfeb.o b/tap/tlstapper/tlstapper_bpfeb.o index 7c62172b056fd114dbbae8ace2b4a7d0300ef33f..cbe4c8a1ae5e21f6489ef30641131a0979a9a732 100644 GIT binary patch literal 116712 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 gJ|U0C5s2ltx;yyrVUaVYrz0U&ex@&Et; literal 66824 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 z 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