All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Siddharth Nayyar" <sidnayyar@google.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH RFC bpf-next 5/7] libbpf: Implement bpf_gen__struct_ops_update_elem() for light skeletons
Date: Fri, 06 Nov 2026 20:39:02 +0000	[thread overview]
Message-ID: <sashiko-outbox-202249@kernel.org> (raw)
In-Reply-To: <20261106-lskel-struct-ops-v1-5-a4486ffc79cb@google.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] libbpf: wrong prog_fd[] stack index in
  bpf_gen__struct_ops_update_elem()
- [Low] libbpf: module BTF FD leak on error path in
  bpf_gen__struct_ops_update_elem()
--

commit 54b2859f2dcde10dc15af7a3b316556b814dfd0e
Author: Siddharth Nayyar <sidnayyar@google.com>

libbpf: Implement bpf_gen__struct_ops_update_elem() for light skeletons

This commit adds bpf_gen__struct_ops_update_elem() and calls it from
bpf_object_prepare_struct_ops() to close attach_btf_obj_fd, copy callback
program file descriptors into kern_vdata, and emit the map update for
struct_ops maps in light skeletons.

> diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
> index aaa491463521a..6dcba83dcc098 100644
> --- a/tools/lib/bpf/gen_loader.c
> +++ b/tools/lib/bpf/gen_loader.c
> @@ -1573,3 +1573,61 @@ void bpf_gen__init_kern_struct_ops(struct bpf_gen *gen, struct btf *btf,
>  		}
>  	}
>  }
> +
> +void bpf_gen__struct_ops_update_elem(struct bpf_gen *gen, int map_idx,
> +				     struct btf *btf,
> +				     struct bpf_struct_ops *st_ops)
> +{
> +	int attr_size = offsetofend(union bpf_attr, flags);
> +	const struct btf_type *type;
> +	union bpf_attr attr;
> +	int key, zero = 0;
> +	__u32 i;
> +
> +	/* 1. Close attach_btf_obj_fd (upper 32 bits of st_ops->type_id_off) */
> +	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_0, BPF_PSEUDO_MAP_IDX_VALUE,
> +					 0, 0, 0, st_ops->type_id_off));
> +	emit(gen, BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0));
> +	emit(gen, BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 32));
> +	__emit_sys_close(gen);

[Severity: Low]
Does this leak attach_btf_obj_fd if an earlier runtime check fails and jumps
to cleanup_label?

When the target struct_ops type is in a kernel module,
bpf_gen__init_kern_struct_ops() stores the module btf file descriptor in the
upper 32 bits of st_ops->type_id_off before map creation and program loading
are emitted.  Because gen->cleanup_label only closes stack file descriptors
and fd_array map file descriptors, any emit_check_err() failure before
reaching bpf_gen__struct_ops_update_elem() leaves attach_btf_obj_fd open.

> +
> +	/* 2. Populate prog_fd into kern_vdata for all callback members */
> +	type = btf__type_by_id(btf, st_ops->type_id);
> +	for (i = 0; i < btf_vlen(type); i++) {
> +		struct bpf_program *prog = st_ops->progs[i];
> +		int prog_idx, off_slot;
> +
> +		if (!prog)
> +			continue;
> +
> +		prog_idx = bpf_program_idx(prog);
> +		off_slot = st_ops->kern_func_off[i];
> +
> +		/* R2 = dynamic kernel member offset from off_slot */
> +		emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
> +						 0, 0, 0, off_slot));
> +		emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0));
> +		emit(gen, BPF_JMP_IMM(BPF_JLE, BPF_REG_2,
> +				      KERN_VDATA_MAX_SIZE - sizeof(__u64), 2));
> +		emit(gen, BPF_MOV64_IMM(BPF_REG_7, -E2BIG));
> +		emit_check_err(gen);
> +
> +		/* R1 = kern_vdata_off + offset */
> +		emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_1, BPF_PSEUDO_MAP_IDX_VALUE,
> +						 0, 0, 0, st_ops->kern_vdata_off));
> +		emit(gen, BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2));
> +
> +		/* R0 = prog_fd from stack (stack_off(prog_fd[prog_idx])) */
> +		emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_10,
> +				      stack_off(prog_fd[prog_idx])));

[Severity: Medium]
Can stack_off(prog_fd[prog_idx]) read the wrong stack slot or go out of
bounds when obj->programs[] contains subprograms or non-autoloaded programs?

bpf_program_idx() returns prog - prog->obj->programs, whereas
bpf_object__load_progs() skips subprograms (such as functions in .text) and
non-autoloaded programs, and bpf_gen__prog_load() stores each loaded
program's file descriptor sequentially at stack_off(prog_fd[gen->nr_progs]):

tools/lib/bpf/gen_loader.c:bpf_gen__prog_load() {
	...
	/* remember prog_fd in the stack, if successful */
	emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7,
			      stack_off(prog_fd[gen->nr_progs])));
	gen->nr_progs++;
}

When any skipped program precedes prog in obj->programs[], prog_idx does not
match the program's slot in prog_fd[], so the generated loader either writes
the wrong file descriptor into kern_vdata or emits an out-of-bounds stack
read that the verifier rejects if prog_idx exceeds the prog_fd[] array size.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-lskel-struct-ops-v1-0-a4486ffc79cb@google.com?part=5

  reply	other threads:[~2026-11-06 20:39 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06 20:19 [PATCH RFC bpf-next 0/7] bpf: Support struct_ops in light skeletons Siddharth Nayyar
2026-11-06 20:19 ` [PATCH RFC bpf-next 1/7] bpf: Add bpf_btf_get_struct_member_info() helper Siddharth Nayyar
2026-11-06 20:37   ` sashiko-bot
2026-11-06 20:56   ` bot+bpf-ci
2026-11-06 20:19 ` [PATCH RFC bpf-next 2/7] libbpf: Implement bpf_gen__init_kern_struct_ops() for light skeletons Siddharth Nayyar
2026-11-06 20:53   ` sashiko-bot
2026-11-06 20:56   ` bot+bpf-ci
2026-11-06 20:19 ` [PATCH RFC bpf-next 3/7] libbpf: Support BPF_MAP_TYPE_STRUCT_OPS in bpf_gen__map_create() Siddharth Nayyar
2026-11-06 20:33   ` sashiko-bot
2026-11-06 20:56   ` bot+bpf-ci
2026-11-06 20:19 ` [PATCH RFC bpf-next 4/7] libbpf: Support BPF_PROG_TYPE_STRUCT_OPS in bpf_gen__prog_load() Siddharth Nayyar
2026-11-06 20:56   ` bot+bpf-ci
2026-11-06 20:19 ` [PATCH RFC bpf-next 5/7] libbpf: Implement bpf_gen__struct_ops_update_elem() for light skeletons Siddharth Nayyar
2026-11-06 20:39   ` sashiko-bot [this message]
2026-11-06 20:56   ` bot+bpf-ci
2026-11-06 20:19 ` [PATCH RFC bpf-next 6/7] bpftool: Generate attach and detach for struct_ops in " Siddharth Nayyar
2026-11-06 20:19 ` [PATCH RFC bpf-next 7/7] selftests/bpf: Add light skeleton struct_ops tests Siddharth Nayyar
2026-11-09 19:46 ` [PATCH RFC bpf-next 0/7] bpf: Support struct_ops in light skeletons Ihor Solodrai
2026-11-09 21:39   ` Alexei Starovoitov
2026-11-10 13:08     ` Anton Protopopov
2026-11-10 13:12     ` Anton Protopopov
2026-11-11  7:35       ` Sid Nayyar

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=sashiko-outbox-202249@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=sidnayyar@google.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.