On 1/2/24 7:11 AM, Bram Schuur wrote:
Me and my colleague Jan-Gerd Tenberge encountered this issue in production on the 5.15, 6.1 and 6.2 kernel versions. We make a small reproducible case that might help find the root cause: simple_repo.c: #include <linux/bpf.h> #include <bpf/bpf_helpers.h> SEC("socket") int socket__http_filter(struct __sk_buff* skb) { volatile __u32 r = bpf_get_prandom_u32(); if (r == 0) { goto done; } #pragma clang loop unroll(full) for (int i = 0; i < 12000; i++) { r += 1; } #pragma clang loop unroll(full) for (int i = 0; i < 12000; i++) { r += 1; } done: return r; } Looking at kernel/bpf/core.c it seems that during constant blinding every instruction which has an constant operand gets 2 additional instructions. This increases the amount of instructions between the JMP and target of the JMP cause rewrite of the JMP to fail because the offset becomes bigger than S16_MAX.
This is indeed possible as verifier might increase insn account in various cases. -mcpu=v4 is designed to solve this problem but it is only available at 6.6 and above.
Hope this helps, Bram Schuur and Jan-Gerd Tenberge