eBPF获取套接字地址族返回异常值问题求助
解决eBPF kprobe读取套接字地址族错误的问题
你的核心问题是kprobe的函数参数定义完全错误,导致你读取的内存地址根本不是struct sock的实例,自然会得到随机的垃圾值。
问题根源
内核中sock_recvmsg的实际函数签名并非直接接收struct sock *,而是:
int sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags);
你把kprobe的入口函数参数定义成struct sock *sk,相当于把第一个参数struct kiocb *iocb的地址当成了sock指针,读取的内存完全不对,所以得到的skc_family是随机值。
修正方案
需要从正确的参数位置获取struct socket *,再通过socket->sk拿到struct sock实例,之后再读取地址族:
#include <linux/socket.h> #include <linux/net.h> #define AF_INET 2 #define AF_INET6 10 SEC("kprobe/sock_recvmsg") int kprobe_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) { if (!sock || !sock->sk) { return 0; } u16 family; // 用bpf_core_read更安全,适配内核结构体偏移变化 bpf_core_read(&family, sizeof(family), &sock->sk->__sk_common.skc_family); bpf_printk("kprobe/sock_recvmsg family: %d", family); if (family == AF_INET || family == AF_INET6) { u32 tid = bpf_get_current_pid_tgid() >> 32; bpf_printk("kprobe/sock_recvmsg tid: %d", tid); u32 value = 1; bpf_map_update_elem(&inetsocket, &tid, &value, BPF_ANY); } return 0; }
额外注意事项
- 如果你的内核版本较旧,
bpf_core_read不可用,可以用bpf_probe_read_kernel替代,但bpf_core_read能自动处理内核结构体的偏移变化,兼容性更好。 - 必须添加空指针检查(
!sock || !sock->sk),避免访问无效内存导致程序崩溃或被内核拒绝加载。 - 同样的问题也会出现在
sock_sendmsg的kprobe中,需要同步修正参数定义。
内容的提问来源于stack exchange,提问作者Ryan Assis
相关产品推荐
相关产品推荐

