All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: sashiko-reviews@lists.linux.dev
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v3 06/13] bpf: Reject callbacks returning more than 8 bytes
Date: Mon, 10 Aug 2026 09:36:11 -0700	[thread overview]
Message-ID: <0e6fd62e-0f69-4ae8-9335-85a139870d81@linux.dev> (raw)
In-Reply-To: <20260808194539.1418B1F000E9@smtp.kernel.org>



On 8/8/26 12:45 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] check_global_subprog_return_code() fails to validate BPF_REG_2 for global subprograms returning > 8 bytes, allowing kernel pointer leaks.
> - [High] BPF-to-BPF calls returning 16-byte values are broken because prepare_func_exit() only copies R0 to the caller, leaving R2 uninitialized.
> - [High] BPF programs cannot use 16-byte returns from kfuncs because check_kfunc_call() fails to initialize BPF_REG_2.
> --
>
> --- Patch [6]: [PATCH bpf-next v3 06/13] bpf: Reject callbacks returning more than 8 bytes ---
> commit d03b8255604638dcb72d6dda989b79be64af9fa4
> Author: Yonghong Song <yonghong.song@linux.dev>
>
> bpf: Reject callbacks returning more than 8 bytes
>
> This patch prevents BPF callbacks passed to helpers, kfuncs, or as exception
> callbacks from returning more than 8 bytes. Since the callback prototypes
> yield a single u64 in R0, returning a 16-byte value would cause the upper
> half to be silently dropped. The verifier now rejects such callbacks at
> load time in check_ld_imm() and do_check_common().
>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -16306,6 +16306,11 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
>>   			verbose(env, "callback function not static\n");
>>   			return -EINVAL;
>>   		}
>> +		if (bpf_ret_reg_pair(env, subprogno)) {
>> +			verbose(env,
>> +				"callback function with >8-byte return value is not supported\n");
>> +			return -EINVAL;
>> +		}
>>   
>>   		dst_reg->type = PTR_TO_FUNC;
>>   		dst_reg->subprogno = subprogno;
> [ ... ]
>
>> @@ -18528,6 +18533,12 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
>>   				ret = -EINVAL;
>>   				goto out;
>>   			}
>> +			if (bpf_ret_reg_pair(env, subprog)) {
>> +				verbose(env,
>> +					"exception cb cannot return value larger than 8 bytes\n");
>> +				ret = -EINVAL;
>> +				goto out;
>> +			}
>>   
>>   			/* Also ensure the callback only has a single scalar argument. */
>>   			if (sub->arg_cnt != 1 || sub->args[0].arg_type != ARG_ANYTHING) {
>
> While reviewing the support for 16-byte return values, I noticed a few other
> places in kernel/bpf/verifier.c that might need updates:
>
> In kernel/bpf/verifier.c:check_global_subprog_return_code():
>
>> 	return check_global_ret_scalar_reg(env, BPF_REG_0);
> [Severity: High]
> Does check_global_subprog_return_code() fail to validate BPF_REG_2 for global
> subprograms returning more than 8 bytes?
>
> A global subprogram returning a 16-byte value (e.g. __int128) could place a
> kernel pointer in BPF_REG_2 and exit without the verifier rejecting it,
> bypassing the verifier's pointer leak prevention.
>
> Although currently unexploitable because callers have R2 marked uninitialized
> due to another issue, if the caller issue is fixed, or if the kernel reads
> the return value directly (e.g. via BPF trampoline), can this missing
> validation become an exploitable KASLR bypass or pointer leak?
>
>
> In kernel/bpf/verifier.c:prepare_func_exit():
>
>> 	/* return to the caller whatever r0 had in the callee */
>> 	caller->regs[BPF_REG_0] = *r0;
> [Severity: High]
> Are BPF-to-BPF calls returning 16-byte values broken here?
>
> This only copies R0 to the caller, leaving R2 uninitialized in the caller's
> frame. BPF programs calling static subprograms that return 16-byte values
> cannot use the upper 64 bits of the return value, as the verifier will reject
> the program with an uninitialized register error.
>
> Additionally, precision backtracking logic added for R2 on static subprog exit
> appears to be rendered unreachable dead code because R2 can never be marked
> precise by the caller.
>
>
> In kernel/bpf/verifier.c:check_kfunc_call():
>
>> 	if (btf_type_is_scalar(t)) {
>> 		mark_reg_unknown(env, regs, BPF_REG_0);
> [Severity: High]
> Can BPF programs actually use 16-byte returns from kfuncs?
>
> This handles scalar return types from kfuncs but only initializes R0, leaving
> R2 uninitialized.
>
> Since caller-saved registers (including R2) are cleared before the call, any
> BPF program attempting to use this new feature will be rejected by the
> verifier when attempting to read R2. Should this also mark R2 as initialized
> for 16-byte scalar returns?

This patch is a preparation patch, in the next commit, proper verifier support
(with returning R2) will be implemented.


  reply	other threads:[~2026-08-10 16:36 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-08 19:03 [PATCH bpf-next v3 00/13] bpf: Support aggregate return values up to 16 bytes Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 01/13] bpf: Factor check_global_ret_scalar_reg() out of the global return check Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 02/13] bpf: Add helpers to describe the R0:R2 return register pair Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 03/13] bpf: Wire up JIT support for 16-byte kfunc returns Yonghong Song
2026-08-08 19:39   ` sashiko-bot
2026-08-10 16:29     ` Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 04/13] bpf: Track R2 of register-pair returns in precision backtracking Yonghong Song
2026-08-08 19:29   ` sashiko-bot
2026-08-10 16:30     ` Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 05/13] bpf: Account R2 of register-pair returns in live register analysis Yonghong Song
2026-08-08 19:03 ` [PATCH bpf-next v3 06/13] bpf: Reject callbacks returning more than 8 bytes Yonghong Song
2026-08-08 19:45   ` sashiko-bot
2026-08-10 16:36     ` Yonghong Song [this message]
2026-08-08 19:03 ` [PATCH bpf-next v3 07/13] bpf: Add verifier support for 16-byte returns in R0:R2 Yonghong Song
2026-08-08 19:41   ` sashiko-bot
2026-08-10 16:44     ` Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 08/13] bpf: Reject register-pair returns when the subprog BTF is unreliable Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 09/13] bpf: Enable aggregate return types up to 16 bytes Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 10/13] selftests/bpf: Add C tests for 16-byte returns in R0:R2 Yonghong Song
2026-08-08 19:27   ` sashiko-bot
2026-08-10 16:51     ` Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 11/13] selftests/bpf: Add inline-asm and subprog tests for R0:R2 returns Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 12/13] selftests/bpf: Add tests for callbacks returning more than 8 bytes Yonghong Song
2026-08-08 19:04 ` [PATCH bpf-next v3 13/13] Documentation/bpf: Document up to 16-byte kfunc return values in R0:R2 Yonghong Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0e6fd62e-0f69-4ae8-9335-85a139870d81@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.