From: Daniel Borkmann Date: Fri, 29 May 2026 09:41:17 +0000 (+0200) Subject: libbpf: Skip hash computation when loader generation failed X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c5e2f1a85844abbb65df4694f5ebad0a13e219c;p=thirdparty%2Fkernel%2Flinux.git libbpf: Skip hash computation when loader generation failed bpf_gen__finish() calls compute_sha_update_offsets() gated only on the gen_hash option, without first consulting gen->error. On a failed generation this is buggy: a failed realloc_data_buf() sets gen->data_start to NULL (leaving gen->data_cur dangling), so compute_sha_update_offsets() runs libbpf_sha256() over a NULL buffer with a bogus length; a failed realloc_insn_buf() likewise sets gen->insn_start to NULL and the hash immediates get patched through that NULL base. The computed program is discarded in either case, since the following "if (!gen->error)" block does not publish opts->insns once an error is set. Thus, skip the hash pass when generation has already failed. Fixes: ea923080c145 ("libbpf: Embed and verify the metadata hash in the loader") Reported-by: sashiko Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/r/20260529094119.307264-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov --- diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c index 7b95ced7bcbaf..3a6e1d53f287a 100644 --- a/tools/lib/bpf/gen_loader.c +++ b/tools/lib/bpf/gen_loader.c @@ -397,13 +397,12 @@ int bpf_gen__finish(struct bpf_gen *gen, int nr_progs, int nr_maps) blob_fd_array_off(gen, i)); emit(gen, BPF_MOV64_IMM(BPF_REG_0, 0)); emit(gen, BPF_EXIT_INSN()); - if (OPTS_GET(gen->opts, gen_hash, false)) - compute_sha_update_offsets(gen); - - pr_debug("gen: finish %s\n", errstr(gen->error)); if (!gen->error) { struct gen_loader_opts *opts = gen->opts; + if (OPTS_GET(opts, gen_hash, false)) + compute_sha_update_offsets(gen); + opts->insns = gen->insn_start; opts->insns_sz = gen->insn_cur - gen->insn_start; opts->data = gen->data_start; @@ -418,6 +417,7 @@ int bpf_gen__finish(struct bpf_gen *gen, int nr_progs, int nr_maps) bpf_insn_bswap(insn++); } } + pr_debug("gen: finish %s\n", errstr(gen->error)); return gen->error; }