All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leon Hwang <leon.hwang@linux.dev>
To: sashiko-reviews@lists.linux.dev, bpf@vger.kernel.org
Cc: linux-trace-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next v5 5/6] libbpf: Add log_opts support for bpf_link_create
Date: Thu, 29 Oct 2026 14:36:30 +0800	[thread overview]
Message-ID: <99bbc23f-a3a0-4357-99d7-0f0167136432@linux.dev> (raw)
In-Reply-To: <sashiko-outbox-185491@kernel.org>

On 27/10/26 00:05, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] libbpf: type confusion between iter_info and log_opts in bpf_link_create()
> --
> 
> commit b4af2771f4c0edb6656b6ddcd881019158c55a55
> Author: Leon Hwang <leon.hwang@linux.dev>
> 
> libbpf: Add log_opts support for bpf_link_create
> 
> This commit adds log_opts support to bpf_link_create() by placing log_opts in
> an anonymous union with iter_info in struct bpf_link_create_opts and passing
> it to __sys_bpf_fd().
> 
>> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
>> index aea534764dfe2..38dcb31e8c0ed 100644
>> --- a/tools/lib/bpf/bpf.c
>> +++ b/tools/lib/bpf/bpf.c
>> @@ -794,6 +794,8 @@ int bpf_link_create(int prog_fd, int target_fd,
>>  {
>>  	const size_t attr_sz = offsetofend(union bpf_attr, link_create);
>>  	__u32 target_btf_id, iter_info_len, relative_id;
>> +	union bpf_iter_link_info *iter_info = NULL;
>> +	struct bpf_log_opts *log_opts = NULL;
>>  	int fd, err, relative_fd;
>>  	union bpf_attr attr;
>>  
>> @@ -803,6 +805,14 @@ int bpf_link_create(int prog_fd, int target_fd,
>>  	iter_info_len = OPTS_GET(opts, iter_info_len, 0);
>>  	target_btf_id = OPTS_GET(opts, target_btf_id, 0);
>>  
>> +	if (iter_info_len && attach_type != BPF_TRACE_ITER)
>> +		return libbpf_err(-EINVAL);
>> +
>> +	if (iter_info_len)
>> +		iter_info = OPTS_GET(opts, iter_info, (void *)0);
>> +	else
>> +		log_opts = OPTS_GET(opts, log_opts, (void *)0);
> 
> [Severity: Medium]
> Can overlaying iter_info and log_opts in struct bpf_link_create_opts and
> selecting between them using only iter_info_len cause type confusion when a
> caller passes a non-NULL iter_info with iter_info_len == 0?

Users must not do like this. By convention, iter_info_len==0 means no
iter_info.

> 
> For example, a caller of bpf_link_create() or bpf_program__attach_iter() in
> tools/lib/bpf/libbpf.c:
> 
> tools/lib/bpf/libbpf.c:bpf_program__attach_iter() {
> 	...
> 	link_create_opts.iter_info = OPTS_GET(opts, link_info, (void *)0);
> 	link_create_opts.iter_info_len = OPTS_GET(opts, link_info_len, 0);
> 	...
> 	return bpf_link_create(prog_fd, target_fd, BPF_TRACE_ITER, &link_create_opts);
> }
> 
> might pass a non-NULL union bpf_iter_link_info pointer while leaving
> iter_info_len (or link_info_len) set to 0.
> 
> Previously, bpf_link_create() forwarded both the non-NULL iter_info pointer
> and iter_info_len == 0 to the kernel, where bpf_iter_link_attach() rejected
> the mismatched arguments with -EINVAL:
> 
> kernel/bpf/bpf_iter.c:bpf_iter_link_attach() {
> 	...
> 	if (bpfptr_is_null(ulinfo) ^ !linfo_len)
> 		return -EINVAL;
> 	...
> }
> 
> With this change, when iter_info_len == 0, bpf_link_create() leaves iter_info
> as NULL (so attr.link_create.iter_info is 0 and the kernel check is bypassed)
> and instead assigns the union bpf_iter_link_info pointer to log_opts.
> 
> When bpf_link_create() then calls __sys_bpf_fd(), log_opts is dereferenced as
> struct bpf_log_opts:
> 
> tools/lib/bpf/bpf.c:__sys_bpf_fd() {
> 	...
> 	if (!OPTS_VALID(log_opts, bpf_log_opts))
> 		return libbpf_err(-EINVAL);
> 
> 	if (log_opts && feat_supported(NULL, FEAT_BPF_SYSCALL_COMMON_ATTRS)) {
> 		memset(&attr_common, 0, attr_common_sz);
> 		attr_common.log_buf = ptr_to_u64(OPTS_GET(log_opts, buf, NULL));
> 		attr_common.log_size = OPTS_GET(log_opts, size, 0);
> 		attr_common.log_level = OPTS_GET(log_opts, level, 0);
> 		fd = sys_bpf_ext_fd(cmd, attr, attr_sz, &attr_common, attr_common_sz);
> 		OPTS_SET(log_opts, true_size, attr_common.log_true_size);
> 	} else {
> 		fd = sys_bpf_fd(cmd, attr, attr_sz);
> 		OPTS_SET(log_opts, true_size, 0);
> 	}
> 	...
> }
> 
> Since union bpf_iter_link_info is 16 bytes while struct bpf_log_opts extends
> to offsetofend(struct bpf_log_opts, true_size) (28 bytes on 64-bit, 20 bytes
> on 32-bit), interpreting the first sizeof(size_t) bytes of iter_info (such as
> map.map_fd, task.tid, task.pid, or cgroup.cgroup_fd) as log_opts->sz can
> cause out-of-bounds reads in OPTS_VALID() and OPTS_GET(), as well as a 4-byte
> out-of-bounds write past union bpf_iter_link_info via OPTS_SET(log_opts,
> true_size, ...).
> 
> In addition, aliasing iter_info and log_opts prevents BPF_TRACE_ITER links
> from using log_opts whenever iter_info is specified. Would it be safer to
> place log_opts in its own field at the end of struct bpf_link_create_opts
> instead of sharing a union with iter_info?
> 

Not at the end of struct bpf_link_create_opts.

When adding log_opts support for iter link in the future, both iter_info
and iter_info_len will be moved to the last union.

diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index fe3b7fd8512b..8bfada1f3ea3 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -478,6 +478,10 @@ struct bpf_link_create_opts {
                        const __u64 *cookies;
                        __u32 cnt;
                } tracing_multi;
+               struct {
+                       union bpf_iter_link_info *info;
+                       __u32 len;
+               } iter;
        };
        size_t :0;
 };

Afterwards, log_opts will be valid at the iter_info position for iter link.

Thanks,
Leon


  reply	other threads:[~2026-10-29  6:36 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26 15:49 [PATCH bpf-next v5 0/6] bpf: Add syscall common attrs support for xdp link_create Leon Hwang
2026-10-26 15:49 ` [PATCH bpf-next v5 1/6] bpf: Add syscall common attrs support for link_create Leon Hwang
2026-10-26 16:06   ` sashiko-bot
2026-10-29  6:35     ` Leon Hwang
2026-10-26 15:49 ` [PATCH bpf-next v5 2/6] bpf: Add syscall common attrs support for xdp link_create Leon Hwang
2026-10-27 23:07   ` Jakub Kicinski
2026-10-26 15:49 ` [PATCH bpf-next v5 3/6] bpf: Retire tracepoint bpf_xdp_link_attach_failed Leon Hwang
2026-10-26 15:49 ` [PATCH bpf-next v5 4/6] libbpf: Factor out __sys_bpf_fd helper Leon Hwang
2026-10-26 15:49 ` [PATCH bpf-next v5 5/6] libbpf: Add log_opts support for bpf_link_create Leon Hwang
2026-10-26 16:05   ` sashiko-bot
2026-10-29  6:36     ` Leon Hwang [this message]
2026-10-29 16:22   ` Andrii Nakryiko
2026-10-26 15:49 ` [PATCH bpf-next v5 6/6] selftests/bpf: Add tests to verify link_create logs Leon Hwang
2026-10-29 16:30 ` [PATCH bpf-next v5 0/6] bpf: Add syscall common attrs support for xdp link_create patchwork-bot+netdevbpf

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=99bbc23f-a3a0-4357-99d7-0f0167136432@linux.dev \
    --to=leon.hwang@linux.dev \
    --cc=bpf@vger.kernel.org \
    --cc=linux-trace-kernel@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.