From 5455e747d71c24774a3c0296c04abe9f50b972ff Mon Sep 17 00:00:00 2001 From: Leon Hwang Date: Tue, 8 Oct 2024 22:12:08 +0800 Subject: [PATCH] Fix verifier error to run --filter-trace-tc + --filter-track-bpf-helpers When to run `./pwru --filter-track-bpf-helpers --filter-trace-tc --filter-func '.*udp.*' --output-limit-lines 10 icmp`, there will be a verifier error: ```log 2024/10/08 13:11:17 Attaching tc-bpf progs... 2024/10/08 13:11:17 failed to trace TC progs: failed to trace bpf progs: failed to load objects: Verifier error: load program: permission denied: func#0 @0 func#1 @43 func#2 @1062 func#3 @1118 0: R1=ctx() R10=fp0 ; int BPF_PROG(fentry_tc, struct sk_buff *skb) { @ kprobe_pwru.c:594 ... ; u64 fp = PT_REGS_FP(ctx); @ kprobe_pwru.c:399 69: (79) r1 = *(u64 *)(r10 -64) ; frame1: R1_w=ctx() R10=fp0 fp-64=ctx() 70: (79) r7 = *(u64 *)(r1 +32) func 'entry2' doesn't have 3-th argument invalid bpf_context access off=32 size=8 processed 51 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1 program fentry_tc: load program: permission denied: func 'entry2' doesn't have 3-th argument: invalid bpf_context access off=32 size=8 (110 line(s) omitted) ``` That's because `fentry` does not support `PT_REGS_FP`. And, there's no way for `fentry` to get FP. So, let us skip getting FP for `fentry_tc`. Signed-off-by: Leon Hwang --- bpf/kprobe_pwru.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bpf/kprobe_pwru.c b/bpf/kprobe_pwru.c index 9e209fce..da708085 100644 --- a/bpf/kprobe_pwru.c +++ b/bpf/kprobe_pwru.c @@ -434,13 +434,13 @@ set_output(void *ctx, struct sk_buff *skb, struct event_t *event) { } static __noinline bool -handle_everything(struct sk_buff *skb, void *ctx, struct event_t *event, u64 *_stackid) { +handle_everything(struct sk_buff *skb, void *ctx, struct event_t *event, u64 *_stackid, const bool is_kprobe) { u8 tracked_by; u64 skb_addr = (u64) skb; u64 skb_head = (u64) BPF_CORE_READ(skb, head); u64 stackid; - if (cfg->track_skb_by_stackid) + if (cfg->track_skb_by_stackid && is_kprobe) stackid = _stackid ? *_stackid : get_stackid(ctx); if (cfg->is_set) { @@ -457,7 +457,7 @@ handle_everything(struct sk_buff *skb, void *ctx, struct event_t *event, u64 *_s goto cont; } - if (cfg->track_skb_by_stackid && bpf_map_lookup_elem(&stackid_skb, &stackid)) { + if (cfg->track_skb_by_stackid && is_kprobe && bpf_map_lookup_elem(&stackid_skb, &stackid)) { tracked_by = TRACKED_BY_STACKID; goto cont; } @@ -479,7 +479,7 @@ handle_everything(struct sk_buff *skb, void *ctx, struct event_t *event, u64 *_s bpf_map_update_elem(&xdp_dhs_skb_heads, &skb_head, &skb_addr, BPF_ANY); } - if (cfg->track_skb_by_stackid && tracked_by != TRACKED_BY_STACKID) { + if (cfg->track_skb_by_stackid && is_kprobe && tracked_by != TRACKED_BY_STACKID) { u64 *old_stackid = bpf_map_lookup_elem(&skb_stackid, &skb); if (old_stackid && *old_stackid != stackid) { bpf_map_delete_elem(&stackid_skb, old_stackid); @@ -499,7 +499,7 @@ static __always_inline int kprobe_skb(struct sk_buff *skb, struct pt_regs *ctx, bool has_get_func_ip, u64 *_stackid) { struct event_t event = {}; - if (!handle_everything(skb, ctx, &event, _stackid)) + if (!handle_everything(skb, ctx, &event, _stackid, true)) return BPF_OK; event.skb_addr = (u64) skb; @@ -596,7 +596,7 @@ SEC("fentry/tc") int BPF_PROG(fentry_tc, struct sk_buff *skb) { struct event_t event = {}; - if (!handle_everything(skb, ctx, &event, NULL)) + if (!handle_everything(skb, ctx, &event, NULL, false)) return BPF_OK; event.skb_addr = (u64) skb;