The static linker sanity-checks relocation sections before appending them, but for executable target sections it only verifies that r_offset is BPF-instruction aligned. It does not verify that the offset is inside the relocated section. A malformed object can therefore pass an out-of-range offset through linker_sanity_check_elf_relos(). When the relocation is against an STT_SECTION symbol, linker_append_elf_relos() uses the unchecked offset to find the instruction to adjust: insn = dst_linked_sec->raw_data + dst_rel->r_offset; and then reads insn->code and updates insn->imm. This is reproducible with bpftool's static linker by crafting a BPF object with a 16-byte executable section and a relocation in its .rel section whose r_offset is 0x1000: BUG: AddressSanitizer: heap-buffer-overflow in linker_append_elf_relos READ of size 1 linker_append_elf_relos bpf_linker_add_file bpf_linker__add_file do_object Reject relocation offsets that are outside the relocated section before any later use. This mirrors the normal object loading path, which already rejects executable relocations whose r_offset is not inside the program section. Fixes: faf6ed321cf6 ("libbpf: Add BPF static linker APIs") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: HyeongJun An --- tools/lib/bpf/linker.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index 78f92c39290a..3eb23da167d2 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -1048,6 +1048,12 @@ static int linker_sanity_check_elf_relos(struct src_obj *obj, struct src_sec *se return -EINVAL; } + if (relo->r_offset >= link_sec->shdr->sh_size) { + pr_warn("ELF relo #%d in section #%zu has invalid offset %zu in %s\n", + i, sec->sec_idx, (size_t)relo->r_offset, obj->filename); + return -EINVAL; + } + if (link_sec->shdr->sh_flags & SHF_EXECINSTR) { if (relo->r_offset % sizeof(struct bpf_insn) != 0) { pr_warn("ELF relo #%d in section #%zu points to missing symbol #%zu in %s\n", -- 2.43.0