Reputation: 129
I couldn't access sk_buff from kprobe function. when i load and run this program, ebpf verifier fails with this. Do anyone know what im doing wrong here?
Error:
2022/04/20 20:56:17 loading objects: field NfHookSlow: program nf_hook_slow: load program: permission denied: ; int BPF_KPROBE(nf_hook_slow, struct sk_buff *skb, struct nf_hook_state *state,
0: (79) r1 = *(u64 *)(r1 +112)
; if (skb)
1: (15) if r1 == 0x0 goto pc+10
R1_w=inv(id=0) R10=fp0
; struct ethhdr *eth = (struct ethhdr *)(skb->head + skb->mac_header);
2: (69) r2 = *(u16 *)(r1 +182)
R1 invalid mem access 'inv'
processed 3 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
kprobe Program:
SEC("kprobe/nf_hook_slow")
int BPF_KPROBE(nf_hook_slow, struct sk_buff *skb, struct nf_hook_state *state,
const struct nf_hook_entries *e, unsigned int s)
{
if (skb)
{
struct ethhdr *eth = (struct ethhdr *)(skb->head + skb->mac_header);
bpf_printk("eth: %d", eth->h_proto);
}
return 0;
}
I have even tried to read from kernel memory(bpf_probe_read_kernel(&proto, sizeof(proto), ð->h_proto);
) and print it but that's also failing
Error:
0: (79) r1 = *(u64 *)(r1 +112)
; if (skb)
1: (15) if r1 == 0x0 goto pc+9
R1_w=inv(id=0) R10=fp0
; struct ethhdr *eth = (struct ethhdr *)(skb->head + skb->mac_header);
2: (69) r2 = *(u16 *)(r1 +182)
R1 invalid mem access 'inv'
processed 3 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Program:
SEC("kprobe/nf_hook_slow")
int BPF_KPROBE(nf_hook_slow, struct sk_buff *skb, struct nf_hook_state *state,
const struct nf_hook_entries *e, unsigned int s)
{
if (skb)
{
struct ethhdr *eth = (struct ethhdr *)(skb->head + skb->mac_header);
u16 proto;
bpf_probe_read_kernel(&proto, sizeof(proto), ð->h_proto);
}
return 0;
}
Upvotes: 1
Views: 495
Reputation: 129
I fixed it. Looks like have to use bpf_probe_read to read any memeber in sk_buff.
#define member_address(source_struct, source_member) \
({ \
void *__ret; \
__ret = (void *)(((char *)source_struct) + offsetof(typeof(*source_struct), source_member)); \
__ret; \
})
#define member_read(destination, source_struct, source_member) \
do \
{ \
bpf_probe_read( \
destination, \
sizeof(source_struct->source_member), \
member_address(source_struct, source_member)); \
} while (0)
SEC("kprobe/nf_hook_slow")
int BPF_KPROBE(nf_hook_slow, struct sk_buff *skb, struct nf_hook_state *state)
{
char *head;
__u16 mac_header, nw_header, tcp_header, eth_proto;
if (skb)
{
member_read(&head, skb, head);
member_read(&mac_header, skb, mac_header);
member_read(&nw_header, skb, network_header);
char *eth_head = head + mac_header;
bpf_probe_read(ð_proto, sizeof(u16), ð_head[12]);
}
}
Upvotes: 0