Re: [PATCH bpf-next v8 3/3] selftests/bpf: Add test for large offset bpf-to-bpf call

Yazhou Tang <[email protected]>
Newsgroups dev.linux.lists.sashiko,org.kernel.vger.bpf
Message-ID <[email protected]>

On 4/29/26 20:49, [email protected] wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] Missing compiler barrier in the inline assembly landing pad allows LLVM to hoist the 'call_happened' load, leading to an infinite recursion loop and kernel panic.
> --
> 
> commit 7a012e4a738e7d37b40994fe21bcf400bb1dd252
> Author: Yazhou Tang <[email protected]>
> 
> selftests/bpf: Add test for large offset bpf-to-bpf call
> 
> This commit adds a selftest to verify verifier and JIT behavior when handling
> bpf-to-bpf calls with relative jump offsets exceeding the s16 boundary. It uses
> an inline assembly block with a .rept directive to generate a large dummy
> subprogram, forcing the verifier to process a jump exceeding the s16 range.
> 
>> diff --git a/tools/testing/selftests/bpf/progs/verifier_call_large_imm.c b/tools/testing/selftests/bpf/progs/verifier_call_large_imm.c
>> new file mode 100644
>> index 000000000000..da52a1c16d05
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/progs/verifier_call_large_imm.c
> 
> [ ... ]
> 
>> +SEC("syscall")
>> +__success __retval(3)
>> +int call_large_imm_test(void *ctx)
>> +{
>> +	/*
>> +	 * Landing pad to handle call error on kernel without the fix,
>> +	 * preventing kernel panic.
>> +	 */
>> +	asm volatile (
>> +	"r0 = 0;"
>> +	".rept 32768;"
>> +	"r0 += 0;"
>> +	".endr;"
>> +	::: "r0");
>> +
>> +	/*
>> +	 * The call_happened variable is 1 only when the call insn wrongly
>> +	 * go back to the landing pad above.
>> +	 */
>> +	if (call_happened == 1) {
> 
> Could this lack of a memory clobber in the inline assembly allow the compiler
> to hoist the load of call_happened to before the inline assembly block?
> 
> Because call_happened is a plain global variable and the asm volatile block
> does not include a "memory" clobber, LLVM is structurally permitted to optimize
> the code by hoisting the load.
> 
> If the load is hoisted and a truncated backwards jump lands inside the
> assembly block on an unpatched kernel, the if condition would evaluate a stale
> register value (0) instead of re-reading memory.
> 
> Will this bypass the termination check, re-execute the target_subprog call,
> and create an infinite recursion loop that overflows the kernel stack?

Yes. I should use __clobber_all in the inline asm.

I will send v9 asap.

> 
>> +		/* A volatile variable is used here to prevent optimization. */
>> +		volatile int flag = -1;
>> +		return flag;
>> +	}
>> +
>> +	call_happened = 1;
>> +
>> +	padding_subprog();
>> +
>> +	return target_subprog();
>> +}
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.