You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
bpf: Fix test errors with *_is_valid_access() verifier hooks on 32-bit
Sequence of ctx checks and rewrites in real world:
1. Possible CO-RE rewrites of access size & offset, maybe breaking #2
2. Verifier env->ops->is_valid_access(), testing access size == sizeof(u64)
3. Verifier env->ops->convert_ctx_access(), rewrite size & offset
Position of access check above is strange, really only works on 64-bit and
likely unnoticed for lack of systematic 32-bit testing.
Test changing *is_valid_access() to always check size != sizeof(u64), but
on 32-bit systems also check size != sizeof(u32)
On 32-bit armhf, test_progs hits ~100 instances of failures such as:
(NOTE: this results from CO-RE relocation patching to u32 load size)
libbpf: prog 'change_tcp_cc': -- BEGIN PROG LOAD LOG --
0: R1=ctx() R10=fp0
; int change_tcp_cc(struct bpf_iter__tcp *ctx) @ bpf_iter_setsockopt.c:40
0: (b4) w2 = 0 ; R2_w=0
; if (!bpf_tcp_sk(ctx->sk_common)) @ bpf_iter_setsockopt.c:46
1: (61) r1 = *(u32 *)(r1 +8)
func 'bpf_iter_tcp' size 4 must be 8
invalid bpf_context access off=8 size=4 is_valid_access=tracing_prog_is_valid_access
processed 2 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
-- END PROG LOAD LOG --
libbpf: prog 'change_tcp_cc': failed to load: -EACCES
libbpf: failed to load object 'bpf_iter_setsockopt'
libbpf: failed to load BPF skeleton 'bpf_iter_setsockopt': -EACCES
serial_test_bpf_iter_setsockopt:FAIL:iter_skel unexpected error: -13
torvalds#21 bpf_iter_setsockopt:FAIL
(NOTE: no error for tests without CO-RE patching which have u64 load size)
This means *_is_valid_access() can't check ctx pointers simply using:
if (size != sizeof(__u64))
return false;
or
if (size != sizeof(void *)
return false;
And what's required instead is a combo like:
if (size != sizeof(__u64) && size != sizeof(long))
return false;
Implement above as convenience function and use in:
- btf_ctx_access()
- cg_sockopt_is_valid_access()
- bpf_skb_is_valid_access()
- sock_addr_is_valid_access()
- sock_ops_is_valid_access()
- sk_msg_is_valid_access()
- flow_dissector_is_valid_access()
This eliminates all 'invalid bpf_context access" errors on 32-bit armhf
except one with nf_is_valid_access() which is fixed in the next patch.
Signed-off-by: Tony Ambardar <[email protected]>
0 commit comments