All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: Feng Yang <yangfeng59949@163.com>,
	ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev,
	song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org,
	emil@etsalapatis.com
Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf v2] bpf: Fix out-of-bounds btf->types write for split BTF
Date: Tue, 27 Oct 2026 12:33:25 -0700	[thread overview]
Message-ID: <5199fa29-64d8-48ab-b591-cbc854750789@linux.dev> (raw)
In-Reply-To: <20261026073654.840705-1-yangfeng59949@163.com>

On 10/26/26 12:36 AM, Feng Yang wrote:
> From: Feng Yang <yangfeng@kylinos.cn>
> 
> btf_add_type() bounds the btf->types array by BTF_MAX_TYPE, but for a
> split BTF the type ids it registers are start_id .. start_id +
> nr_types - 1, so what is actually left of the id space is
> BTF_MAX_TYPE - start_id.  Two things follow from that:
> 
>  - the limit check is an equality test,
>    'start_id + btf->types_size == BTF_MAX_TYPE'.  It is evaluated only
>    when the array has to grow, with btf->types_size == btf->nr_types,
>    and the growth (T' = min(BTF_MAX_TYPE, T + max(T / 4, 16)), starting
>    from 0) is clamped to BTF_MAX_TYPE, which it lands on exactly (...,
>    928143, then min(BTF_MAX_TYPE, 1160178)).  So unless
>    BTF_MAX_TYPE - start_id is one of the 48 sizes that sequence hits,
>    the check does not fire for a split BTF at all;
> 
>  - new_size is clamped to BTF_MAX_TYPE instead of
>    BTF_MAX_TYPE - start_id, so the array can still grow to
>    BTF_MAX_TYPE entries even though only BTF_MAX_TYPE - start_id type
>    ids exist.
> 
> As a result nr_types can reach BTF_MAX_TYPE for a split BTF while its
> type ids have already gone past BTF_MAX_TYPE; a type never validates its
> own id, only the ids it references (btf_ref_type_check_meta()).  At that
> point btf->types_size == btf->nr_types == BTF_MAX_TYPE and the growth
> branch computes the same size again: it allocates a fresh BTF_MAX_TYPE
> entry array, copies the entries, and the loop is left with
> btf->types_size != btf->nr_types, so that branch is not taken anymore.
> Every type after this writes btf->types[btf->nr_types++] past the end of
> the array: BTF_MAX_TYPE * 8 == 8388600 bytes are requested, so the first
> such write lands in the 8 byte rounding slack of the 8MB allocation, and
> each further type writes another 8 bytes beyond it.
> 
> Fix both by bounding the array with BTF_MAX_TYPE - start_id and by
> turning the equality check into a '>=' one, so that the array stops
> exactly where the id space ends. Base BTF behavior (start_id ==
> 0) is unchanged.
> 
> Fixes: 951bb64621b8 ("bpf: Add in-kernel split BTF support")
> Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
> Reviewed-by: Mahe Tardy <mahe.tardy@gmail.com>
> ---
>  kernel/bpf/btf.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 7ed1ff71a089..ca49c47f6a45 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -1752,15 +1752,17 @@ static int btf_add_type(struct btf_verifier_env *env, struct btf_type *t)
>  		/* Expand 'types' array */
>  
>  		struct btf_type **new_types;
> -		u32 expand_by, new_size;
> +		u32 expand_by, new_size, max_size;
>  
> -		if (btf->start_id + btf->types_size == BTF_MAX_TYPE) {
> +		if (btf->start_id >= BTF_MAX_TYPE ||
> +		    btf->start_id + btf->types_size >= BTF_MAX_TYPE) {

Hi, thanks for the patch.

The fix makes sense to me, however the commit message is difficult to parse.
Do you mind respinning with a more concise explanation of the bug and fix?

This should help: https://docs.kernel.org/process/maintainer-tip.html#changelog

pr-bot: cr


>  			btf_verifier_log(env, "Exceeded max num of types");
>  			return -E2BIG;
>  		}
>  
> +		max_size = BTF_MAX_TYPE - btf->start_id;
>  		expand_by = max_t(u32, btf->types_size >> 2, 16);
> -		new_size = min_t(u32, BTF_MAX_TYPE,
> +		new_size = min_t(u32, max_size,
>  				 btf->types_size + expand_by);
>  
>  		new_types = kvzalloc_objs(*new_types, new_size,


      reply	other threads:[~2026-10-27 19:33 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26  7:36 [PATCH bpf v2] bpf: Fix out-of-bounds btf->types write for split BTF Feng Yang
2026-10-27 19:33 ` Ihor Solodrai [this message]

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=5199fa29-64d8-48ab-b591-cbc854750789@linux.dev \
    --to=ihor.solodrai@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=song@kernel.org \
    --cc=yangfeng59949@163.com \
    --cc=yonghong.song@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.