diff --git a/bpf/http_sock.c b/bpf/http_sock.c index 16ecbc597..15b569df9 100644 --- a/bpf/http_sock.c +++ b/bpf/http_sock.c @@ -29,7 +29,7 @@ struct { // Temporary tracking of tcp_recvmsg arguments typedef struct recv_args { u64 sock_ptr; // linux sock or socket address - u64 iovec_ptr; + u8 iovec_ctx[sizeof(iovec_iter_ctx)]; } recv_args_t; struct { @@ -426,9 +426,10 @@ int BPF_KPROBE(kprobe_tcp_recvmsg, struct sock *sk, struct msghdr *msg, size_t l recv_args_t args = { .sock_ptr = (u64)sk, - .iovec_ptr = (u64)(msg) }; + get_iovec_ctx((iovec_iter_ctx *)&args.iovec_ctx, msg); + bpf_map_update_elem(&active_recv_args, &id, &args, BPF_ANY); return 0; @@ -443,7 +444,9 @@ static __always_inline int return_recvmsg(void *ctx, u64 id, int copied_len) { goto done; } - if (!args->iovec_ptr) { + iovec_iter_ctx *iov_ctx = (iovec_iter_ctx *)&args->iovec_ctx; + + if (!iov_ctx->iov && !iov_ctx->ubuf) { bpf_dbg_printk("iovec_ptr found in kprobe is NULL, ignoring this tcp_recvmsg"); bpf_map_delete_elem(&active_recv_args, &id); @@ -452,7 +455,6 @@ static __always_inline int return_recvmsg(void *ctx, u64 id, int copied_len) { pid_connection_info_t info = {}; - void *iovec_ptr = (void *)args->iovec_ptr; void *sock_ptr = (void *)args->sock_ptr; bpf_map_delete_elem(&active_recv_args, &id); @@ -470,7 +472,7 @@ static __always_inline int return_recvmsg(void *ctx, u64 id, int copied_len) { if (!active_ssl) { u8* buf = iovec_memory(); if (buf) { - copied_len = read_msghdr_buf((void *)iovec_ptr, buf, copied_len); + copied_len = read_iovec_ctx(iov_ctx, buf, copied_len); if (copied_len) { // doesn't return must be logically last statement handle_buf_with_connection(ctx, &info, buf, copied_len, NO_SSL, TCP_RECV, orig_dport); diff --git a/bpf/protocol_common.h b/bpf/protocol_common.h index f83450aaa..9240ea2a2 100644 --- a/bpf/protocol_common.h +++ b/bpf/protocol_common.h @@ -110,6 +110,8 @@ enum iter_type___dummy { // extracts kernel specific iov_iter information into a iovec_iter_ctx instance static __always_inline void get_iovec_ctx(iovec_iter_ctx* ctx, struct msghdr *msg) { + ctx->ubuf = NULL; + ctx->iov = NULL; if (bpf_core_field_exists(((struct iov_iter___dummy*)&msg->msg_iter)->type)) { // clear the direction bit when reading iovec_iter::type to end up // with the original enumerator value (the direction bit is the LSB @@ -121,34 +123,26 @@ static __always_inline void get_iovec_ctx(iovec_iter_ctx* ctx, struct msghdr *ms if (bpf_core_field_exists(((struct iov_iter___dummy*)&msg->msg_iter)->ubuf)) { ctx->ubuf = BPF_CORE_READ((struct iov_iter___dummy*)&msg->msg_iter, ubuf); - } else { - ctx->ubuf = NULL; } if (bpf_core_field_exists(((struct iov_iter___dummy*)&msg->msg_iter)->iov)) { ctx->iov = BPF_CORE_READ((struct iov_iter___dummy*)&msg->msg_iter, iov); } else if (bpf_core_field_exists(((struct iov_iter___dummy*)&msg->msg_iter)->__iov)) { ctx->iov = BPF_CORE_READ((struct iov_iter___dummy*)&msg->msg_iter, __iov); - } else { - ctx->iov = NULL; } ctx->nr_segs = BPF_CORE_READ((struct iov_iter___dummy*)&msg->msg_iter, nr_segs); } -static __always_inline int read_msghdr_buf(struct msghdr *msg, u8* buf, size_t max_len) { +static __always_inline int read_iovec_ctx(iovec_iter_ctx *ctx, u8* buf, size_t max_len) { if (max_len == 0) { return 0; } bpf_clamp_umax(max_len, IO_VEC_MAX_LEN); - iovec_iter_ctx ctx; - - get_iovec_ctx(&ctx, msg); - - bpf_dbg_printk("iter_type=%u", ctx.iter_type); - bpf_dbg_printk("nr_segs=%lu, iov=%p, ubuf=%p", ctx.nr_segs, ctx.iov, ctx.ubuf); + bpf_dbg_printk("iter_type=%u", ctx->iter_type); + bpf_dbg_printk("nr_segs=%lu, iov=%p, ubuf=%p", ctx->nr_segs, ctx->iov, ctx->ubuf); // ITER_UBUF only exists in kernels >= 6.0 - earlier kernels use ITER_IOVEC if (bpf_core_enum_value_exists(enum iter_type___dummy, ITER_UBUF)) { @@ -156,15 +150,15 @@ static __always_inline int read_msghdr_buf(struct msghdr *msg, u8* buf, size_t m // ITER_UBUF is never a bitmask, and can be 0, so we perform a proper // equality check rather than a bitwise and like we do for ITER_IOVEC - if (ctx.ubuf != NULL && ctx.iter_type == iter_ubuf) { + if (ctx->ubuf != NULL && ctx->iter_type == iter_ubuf) { bpf_clamp_umax(max_len, IO_VEC_MAX_LEN); - return bpf_probe_read(buf, max_len, ctx.ubuf) == 0 ? max_len : 0; + return bpf_probe_read(buf, max_len, ctx->ubuf) == 0 ? max_len : 0; } } const int iter_iovec = bpf_core_enum_value(enum iter_type, ITER_IOVEC); - if (ctx.iter_type != iter_iovec) { + if (ctx->iter_type != iter_iovec) { return 0; } @@ -172,17 +166,17 @@ static __always_inline int read_msghdr_buf(struct msghdr *msg, u8* buf, size_t m enum { max_segments = 4 }; - bpf_clamp_umax(ctx.nr_segs, max_segments); + bpf_clamp_umax(ctx->nr_segs, max_segments); // Loop couple of times reading the various io_vecs - for (unsigned long i = 0; i < ctx.nr_segs && i < max_segments; i++) { + for (unsigned long i = 0; i < ctx->nr_segs && i < max_segments; i++) { struct iovec vec; - if (bpf_probe_read_kernel(&vec, sizeof(vec), &ctx.iov[i]) != 0) { + if (bpf_probe_read_kernel(&vec, sizeof(vec), &ctx->iov[i]) != 0) { break; } - // bpf_dbg_printk("iov[%d]=%llx", i, &ctx.iov[i]); + // bpf_dbg_printk("iov[%d]=%llx", i, &ctx->iov[i]); // bpf_dbg_printk("base %llx, len %d", vec.iov_base, vec.iov_len); if (!vec.iov_base || !vec.iov_len) { @@ -211,6 +205,18 @@ static __always_inline int read_msghdr_buf(struct msghdr *msg, u8* buf, size_t m return tot_len; } +static __always_inline int read_msghdr_buf(struct msghdr *msg, u8* buf, size_t max_len) { + if (max_len == 0) { + return 0; + } + + iovec_iter_ctx ctx; + + get_iovec_ctx(&ctx, msg); + + return read_iovec_ctx(&ctx, buf, max_len); +} + // We sort the connection info to ensure we can track requests and responses. However, if the destination port // is somehow in the ephemeral port range, it can be higher than the source port and we'd use the sorted connection // info in user space, effectively reversing the flow of the operation. We keep track of the original destination port diff --git a/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.go index 49ccd9863..46d070f3c 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.go @@ -124,7 +124,7 @@ type bpfPidKeyT struct { type bpfRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpfSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.o index 9468560e8..588aaac8b 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.go index 2b520ef11..92ca08e0b 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.go @@ -124,7 +124,7 @@ type bpf_debugPidKeyT struct { type bpf_debugRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_debugSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.o index a33bb717f..0ce753a05 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_debug_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.go index ecc672e50..141bb3db1 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.go @@ -124,7 +124,7 @@ type bpf_debugPidKeyT struct { type bpf_debugRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_debugSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.o index 11b6b0b64..13d7587b6 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_debug_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.go index d0e667681..157dbff1d 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.go @@ -124,7 +124,7 @@ type bpf_tpPidKeyT struct { type bpf_tpRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_tpSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.o index 373b07121..11102ebef 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.go index 895b3fe7f..e2155d00f 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.go @@ -124,7 +124,7 @@ type bpf_tp_debugPidKeyT struct { type bpf_tp_debugRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_tp_debugSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.o index 64c6199f9..a27f1a31e 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.go index 5b3bac597..1b93954d3 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.go @@ -124,7 +124,7 @@ type bpf_tp_debugPidKeyT struct { type bpf_tp_debugRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_tp_debugSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.o index 443e5aa70..bb1b1d7c5 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.go index 94e4244ff..fc772dc90 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.go @@ -124,7 +124,7 @@ type bpf_tpPidKeyT struct { type bpf_tpRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpf_tpSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.o index 12cc8f6a7..d7e5e6593 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.go b/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.go index ccdb833ae..ef86fa1e0 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.go +++ b/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.go @@ -124,7 +124,7 @@ type bpfPidKeyT struct { type bpfRecvArgsT struct { SockPtr uint64 - IovecPtr uint64 + IovecCtx [40]uint8 } type bpfSendArgsT struct { diff --git a/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.o b/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.o index 795c20900..73b6885d7 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.o and b/pkg/internal/ebpf/httpfltr/bpf_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_arm64_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_arm64_bpfel.o index 31ad29146..c04f772f5 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_arm64_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_arm64_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_debug_arm64_bpfel.o index 6637f7e86..bac080b80 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_debug_arm64_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_debug_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_x86_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_debug_x86_bpfel.o index 158a0ea04..1bff63809 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_debug_x86_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_debug_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_arm64_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_tp_arm64_bpfel.o index 09450b7ff..46392be75 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_arm64_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_tp_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_arm64_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_tp_debug_arm64_bpfel.o index 658b57386..11c5e70b8 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_debug_arm64_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_tp_debug_arm64_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_x86_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_tp_debug_x86_bpfel.o index b55c676a2..24bb549c6 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_debug_x86_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_tp_debug_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_x86_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_tp_x86_bpfel.o index 602afb3f1..9c567291e 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_x86_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_tp_x86_bpfel.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_x86_bpfel.o b/pkg/internal/ebpf/httpssl/bpf_x86_bpfel.o index 73233b7db..2373b0412 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_x86_bpfel.o and b/pkg/internal/ebpf/httpssl/bpf_x86_bpfel.o differ