eBPF:挂接到security_socket_connect时如何读取sockaddr结构

时间:2019-06-10 12:40:58

标签: c linux-kernel bpf ebpf

按照演示文稿Security Monitoring with eBPF中的建议,我试图加入security_socket_connect

虽然我的基于gobpf / bcc的代码部分起作用,但我似乎无法读取sockaddr结构中的IP地址。

相关部分如下:

int security_socket_connect_entry(struct pt_regs *ctx, struct socket *sock, struct sockaddr *address, int addrlen)
{    
    u32 address_family = address->sa_family;
    if (address_family == AF_INET) {
        struct ipv4_data_t data4 = {.pid = pid};

        struct sockaddr_in *addr2 = (struct sockaddr_in *)address;

之后,我尝试读取addr2中的IP地址。第一次尝试是:

data4.daddr = addr2->sin_addr.s_addr;

第二次尝试是使用bpf_probe_read

bpf_probe_read(&data4.daddr, sizeof(data4.daddr), (void *)((long)addr2->sin_addr.s_addr));

两个选项都出现相同的错误:

R9 invalid mem access 'inv'

HINT: The invalid mem access 'inv' error can happen if you try to dereference memory without first using bpf_probe_read() to copy it to the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter, other times you'll need to be explicit. 

可在此处找到带有可构建示例的存储库:socket-connect-bpf

1 个答案:

答案 0 :(得分:2)

多亏了an answer to issue #1858中的bcc repo,我才明白了。

我们必须对指针进行操作,这样才能读取IP地址:

bpf_probe_read(&data4.daddr, sizeof(data4.daddr), &addr2->sin_addr.s_addr);