All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jay Wang" <wanjay@amazon.com>
Cc: bpf@vger.kernel.org, linux-modules@vger.kernel.org
Subject: Re: [PATCH bpf-next 5/6] bpf: defer registrations until the vmlinux BTF is available
Date: Wed, 23 Sep 2026 05:56:32 +0000	[thread overview]
Message-ID: <20260923055633.5B74C1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260923053948.30617-6-wanjay@amazon.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] bpf: UAF in sysfs reader on module BTF alloc ID failure
- [High] bpf: data corruption via un-synchronized kfunc registrations
- [Medium] bpf: race condition causes transient BPF program load failures
- [Medium] bpf: memory leak of vmlinux deferred queue on alloc ID failure
--

commit 7468b94a7c4356b1f1498b95a9030eec1830ffa1
Author: Jay Wang <wanjay@amazon.com>
Subject: bpf: defer registrations until the vmlinux BTF is available

This commit changes the BPF subsystem to defer kfunc, dtor kfunc, and
struct_ops registrations until the vmlinux BTF is parsed. This allows
configuring CONFIG_DEBUG_INFO_BTF as a module so it doesn't need to be parsed
at boot if not required.

> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index 50eb7a95fd825..cbba20a908e9d 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
[ ... ]
> @@ -6581,7 +6583,15 @@ struct btf *btf_parse_vmlinux(void)
>  	if (err) {
>  		btf_free(btf);
>  		btf = ERR_PTR(err);
> +		goto err_out;
>  	}
> +
> +	/*
> +	 * With CONFIG_DEBUG_INFO_BTF=m, kfunc, dtor kfunc and struct_ops
> +	 * registrations for vmlinux made before the BTF was available were
> +	 * queued; apply them now, before the BTF becomes visible to anyone.
> +	 */
> +	btf_apply_deferred_vmlinux_regs(btf);
>  err_out:
>  	btf_verifier_env_free(env);
>  	return btf;

[Severity: Medium]
When btf_alloc_id() fails, the code jumps to err_out, which bypasses the call
to btf_apply_deferred_vmlinux_regs(). Does this leave the items in the
btf_vmlinux_deferred_regs queue stranded, causing a memory leak for those
dynamically allocated deferred registrations? Also, since
btf_vmlinux_regs_closed is never set, would subsequent registrations continue
to queue infinitely?

[ ... ]
> @@ -8905,6 +9033,87 @@ static int __init btf_module_init(void)
>  }
>  
>  fs_initcall(btf_module_init);
> +
> +#if IS_MODULE(CONFIG_DEBUG_INFO_BTF)
> +/*
> + * CONFIG_DEBUG_INFO_BTF=m: the vmlinux BTF has just become available.  Parse
> + * the BTF of the modules that were loaded before it, and apply the
> + * registrations that waited for them.  Called from bpf_get_btf_vmlinux()
> + * once btf_vmlinux is published, with no locks held.
> + */
> +void btf_parse_deferred_modules(void)
> +{
[ ... ]
> +		err = PTR_ERR_OR_ZERO(btf);
> +		if (!err) {
> +			err = btf_alloc_id(btf);
> +			if (err) {
> +				/* btf owns the data now, btf_free() drops it */
> +				btf_mod->data = NULL;
> +				btf_free(btf);
> +			}
> +		}
> +		if (err) {
> +			/*
> +			 * The module is loaded and stays.  Unlike at load time
> +			 * there is no way to reject it, so drop its BTF.
> +			 */
> +			pr_warn("failed to validate module [%s] BTF: %d\n",
> +				btf_mod->module->name, err);
> +			list_del(&btf_mod->list);
> +			btf_module_free(btf_mod);
> +			continue;
> +		}

[Severity: High]
Could the btf_free() call above introduce a use-after-free window for
concurrent sysfs readers? The backing buffer btf->data (which was originally
btf_mod->data) is freed by btf_free(). Even though btf_mod->data is set to
NULL, the sysfs file for the module remains active until btf_module_free()
removes it. If there is a concurrent read to /sys/kernel/btf/<module>, can it
dereference the freed attr->private pointer?

[ ... ]
> +		/* btf->data is btf_mod->data now, the sysfs file keeps working */
> +		btf_mod->data = NULL;
> +		kvfree(btf_mod->base_data);
> +		btf_mod->base_data = NULL;
> +		btf_mod->btf = btf;
> +		parsed = true;

[Severity: Medium]
Here btf_mod->btf is assigned, which makes the module BTF visible globally.
Since this happens before the deferred kfuncs and struct_ops are actually
registered, is there a race condition where a concurrent BPF program load
attempts to use this BTF, but fails verification because the kfuncs are not
yet in the module's kfunc_set_tab?

> +
> +		/*
> +		 * Registrations are applied after dropping the mutex (they
> +		 * walk btf_modules); pin what they need until then.
> +		 */
> +		list_for_each_entry_safe(reg, rtmp, &btf_mod->deferred_regs, list) {
> +			list_del(&reg->list);
> +			if (!try_module_get(btf_mod->module)) {
> +				btf_free_deferred_reg(reg);
> +				continue;
> +			}
> +			btf_get(btf);
> +			reg->btf = btf;
> +			reg->module = btf_mod->module;
> +			list_add_tail(&reg->list, &regs);
> +		}
> +	}
> +	mutex_unlock(&btf_module_mutex);
> +
> +	if (parsed)
> +		purge_cand_cache(NULL);
> +	btf_apply_deferred_regs(&regs);
> +}
> +#endif /* IS_MODULE(CONFIG_DEBUG_INFO_BTF) */

[Severity: High]
Is it possible for data corruption to occur here due to concurrent kfunc
registrations? Because the btf_module_mutex is dropped and btf_mod->btf has
already been set, a concurrent module initcall could perform a new
register_btf_kfunc_id_set(). Since btf_mod->btf is no longer NULL, it would
bypass the deferral queue and proceed to btf_kfunc_id_set_add() directly.

If btf_apply_deferred_regs() is running simultaneously, both paths could
concurrently invoke btf_populate_kfunc_set(), which mutates btf->kfunc_set_tab
without synchronization:

kernel/bpf/btf.c:btf_populate_kfunc_set() {
    ...
	/* Grow set */
	set = krealloc(tab->sets[hook],
		       struct_size(set, pairs, set_cnt + add_set->cnt),
		       GFP_KERNEL | __GFP_NOWARN);
	if (!set) {
		ret = -ENOMEM;
		goto end;
	}

	/* For newly allocated set, initialize set->cnt to 0 */
	if (!tab->sets[hook])
		set->cnt = 0;
	tab->sets[hook] = set;
    ...
}

Would this result in double-free or use-after-free on the krealloc, or lost
kfunc registrations?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260923053948.30617-1-wanjay@amazon.com?part=5

  reply	other threads:[~2026-09-23  5:56 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23  5:39 [PATCH bpf-next 0/6] bpf: make the vmlinux BTF an on-demand loadable module (CONFIG_DEBUG_INFO_BTF=m) to save ~5.4 MB memory Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 1/6] bpf: pass the vmlinux BTF to btf_parse_module() and let it adopt the data Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 2/6] bpf: split the kfunc, dtor kfunc and struct_ops registration bodies Jay Wang
2026-09-23  6:16   ` bot+bpf-ci
2026-09-25 23:02     ` Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 3/6] bpf: fetch the vmlinux BTF where kernel types enter a program Jay Wang
2026-09-23  6:04   ` sashiko-bot
2026-09-25 23:02     ` Jay Wang
2026-09-23  6:28   ` bot+bpf-ci
2026-09-24 11:26     ` Jiri Olsa
2026-09-25 23:02       ` Jay Wang
2026-09-25 23:02     ` Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 4/6] bpf: take the vmlinux BTF from the btf_vmlinux module Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 5/6] bpf: defer registrations until the vmlinux BTF is available Jay Wang
2026-09-23  5:56   ` sashiko-bot [this message]
2026-09-25 23:02     ` Jay Wang
2026-09-23  6:41   ` bot+bpf-ci
2026-09-25 23:02     ` Jay Wang
2026-09-23  5:39 ` [PATCH bpf-next 6/6] kbuild, bpf: allow building the vmlinux BTF as a module Jay Wang
2026-09-23  5:59   ` sashiko-bot
2026-09-25 23:02     ` Jay Wang
2026-09-23  8:27 ` [PATCH bpf-next 0/6] bpf: make the vmlinux BTF an on-demand loadable module (CONFIG_DEBUG_INFO_BTF=m) to save ~5.4 MB memory Alan Maguire
2026-09-25 21:23   ` Jay Wang

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=20260923055633.5B74C1F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=linux-modules@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wanjay@amazon.com \
    /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.