All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx
@ 2026-07-13 13:16 Naveed Khan
  2026-07-13 13:35 ` sashiko-bot
  2026-07-17  0:53 ` Ihor Solodrai
  0 siblings, 2 replies; 3+ messages in thread
From: Naveed Khan @ 2026-07-13 13:16 UTC (permalink / raw)
  To: bpf

linker_sanity_check_elf_symtab() only validates a symbol's st_shndx
against the section count when it is below SHN_LORESERVE:

	if (sym->st_shndx < SHN_LORESERVE && sym->st_shndx >= obj->sec_cnt)
		return -EINVAL;

For a STT_SECTION symbol the following check only rejects a non-zero
st_value, so a section symbol carrying a reserved index such as
SHN_ABS (0xfff1) with st_value == 0 passes validation.

When a relocation references such a symbol, linker_append_elf_relos()
indexes the per-object section array with no bound check:

	if (ELF64_ST_TYPE(src_sym->st_info) == STT_SECTION) {
		struct src_sec *sec = &obj->secs[src_sym->st_shndx];
		...
			insn->imm += sec->dst_off;

obj->secs holds only obj->sec_cnt entries, so obj->secs[0xfff1]
dereferences memory tens of thousands of entries past the allocation
(reading sec->dst_off) when linking a crafted relocatable object,
an out-of-bounds read that faults or folds unrelated heap contents
into the patched instruction.

A STT_SECTION symbol must reference a real section, so reject one whose
st_shndx is not a valid section index. Reserved indices are always
>= SHN_LORESERVE, which exceeds sec_cnt, and the in-range case is
already handled above, so a single sec_cnt bound closes the gap without
affecting valid inputs.

Signed-off-by: Naveed Khan <naveed@digiscrypt.com>
---
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
index 78f92c3929..8a93faa41d 100644
--- a/tools/lib/bpf/linker.c
+++ b/tools/lib/bpf/linker.c
@@ -973,7 +973,7 @@ static int linker_sanity_check_elf_symtab(struct src_obj *obj, struct src_sec *s
 			return -EINVAL;
 		}
 		if (sym_type == STT_SECTION) {
-			if (sym->st_value != 0)
+			if (sym->st_value != 0 || sym->st_shndx >= obj->sec_cnt)
 				return -EINVAL;
 			continue;
 		}
-- 
2.52.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx
  2026-07-13 13:16 [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx Naveed Khan
@ 2026-07-13 13:35 ` sashiko-bot
  2026-07-17  0:53 ` Ihor Solodrai
  1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-13 13:35 UTC (permalink / raw)
  To: Naveed Khan; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Missing bounds check on relocation `r_offset` allows arbitrary out-of-bounds heap read/write during ELF linking.
- [High] A NULL pointer dereference occurs in `linker_append_elf_sym` when resolving global symbols with reserved section indices (e.g., `SHN_ABS`).
- [High] Integer overflow in `sym_idx` bounds check on 32-bit systems allows massive out-of-bounds heap read and information leak.
--

--- Patch [1]: [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx ---
commit a15a7b75755bef67d993d3117ac49d59af2c299e
Author: Naveed Khan <naveed@digiscrypt.com>

libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx

This patch adds a bounds check in linker_sanity_check_elf_symtab() to
ensure that STT_SECTION symbols do not have an out-of-range st_shndx.
This prevents out-of-bounds reads when processing relocations against
such symbols.

> diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
> index 78f92c39290af..8a93faa41d903 100644
> --- a/tools/lib/bpf/linker.c
> +++ b/tools/lib/bpf/linker.c
> @@ -973,7 +973,7 @@ static int linker_sanity_check_elf_symtab(struct src_obj *obj, struct src_sec *s
>  			return -EINVAL;
>  		}
>  		if (sym_type == STT_SECTION) {
> -			if (sym->st_value != 0)
> +			if (sym->st_value != 0 || sym->st_shndx >= obj->sec_cnt)
>  				return -EINVAL;
>  			continue;
>  		}

[Severity: High]
This isn't a bug introduced by this patch, but can we experience a NULL
pointer dereference in linker_append_elf_sym() when resolving global symbols
with reserved section indices like SHN_ABS?

When resolving a global symbol, we update the destination symbol:

tools/lib/bpf/linker.c:linker_append_elf_sym() {
    ...
		dst_sym->st_shndx = dst_sec->sec_idx;
		dst_sym->st_value = src_sec->dst_off + sym->st_value;
		dst_sym->st_size = sym->st_size;
    ...
}

If the symbol uses a reserved section index, could src_sec and dst_sec be
NULL, causing a crash here?


[Severity: Critical]
This is a pre-existing issue, but does linker_sanity_check_elf_relos() miss a
bounds check on the relocation offset against the section size?

tools/lib/bpf/linker.c:linker_sanity_check_elf_relos() {
    ...
		if (link_sec->shdr->sh_flags & SHF_EXECINSTR) {
			if (relo->r_offset % sizeof(struct bpf_insn) != 0) {
    ...
}

Without validating r_offset against the section size, when
linker_append_elf_relos() processes relocations, could it lead to an
out-of-bounds heap read and write?

tools/lib/bpf/linker.c:linker_append_elf_relos() {
    ...
					insn = dst_linked_sec->raw_data + dst_rel->r_offset;
					if (insn->code == (BPF_JMP | BPF_CALL))
						insn->imm += sec->dst_off / sizeof(struct bpf_insn);
					else
						insn->imm += sec->dst_off;
    ...
}


[Severity: High]
This is a pre-existing issue, but can the symbol index bounds check overflow
on 32-bit systems?

tools/lib/bpf/linker.c:linker_sanity_check_elf_relos() {
    ...
		if (!sym_idx || sym_idx * sizeof(Elf64_Sym) >= sym_sec->shdr->sh_size) {
    ...
}

If sym_idx is maliciously crafted (e.g., 0xaaaaaaab), could the multiplication
wrap around and bypass the check?

Later in linker_append_elf_relos(), the unchecked index is used to access
the symbol map:

tools/lib/bpf/linker.c:linker_append_elf_relos() {
    ...
			dst_sym_idx = obj->sym_map[src_sym_idx];
    ...
}

Could this lead to an out-of-bounds heap read being leaked into the relocated
output?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/178394859382.2.942623981274846749@digiscrypt.com?part=1

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx
  2026-07-13 13:16 [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx Naveed Khan
  2026-07-13 13:35 ` sashiko-bot
@ 2026-07-17  0:53 ` Ihor Solodrai
  1 sibling, 0 replies; 3+ messages in thread
From: Ihor Solodrai @ 2026-07-17  0:53 UTC (permalink / raw)
  To: Naveed Khan, bpf

On 7/13/26 6:16 AM, Naveed Khan wrote:
> linker_sanity_check_elf_symtab() only validates a symbol's st_shndx
> against the section count when it is below SHN_LORESERVE:
> 
> 	if (sym->st_shndx < SHN_LORESERVE && sym->st_shndx >= obj->sec_cnt)
> 		return -EINVAL;
> 
> For a STT_SECTION symbol the following check only rejects a non-zero
> st_value, so a section symbol carrying a reserved index such as
> SHN_ABS (0xfff1) with st_value == 0 passes validation.
> 
> When a relocation references such a symbol, linker_append_elf_relos()
> indexes the per-object section array with no bound check:
> 
> 	if (ELF64_ST_TYPE(src_sym->st_info) == STT_SECTION) {
> 		struct src_sec *sec = &obj->secs[src_sym->st_shndx];
> 		...
> 			insn->imm += sec->dst_off;
> 
> obj->secs holds only obj->sec_cnt entries, so obj->secs[0xfff1]
> dereferences memory tens of thousands of entries past the allocation
> (reading sec->dst_off) when linking a crafted relocatable object,
> an out-of-bounds read that faults or folds unrelated heap contents
> into the patched instruction.
> 
> A STT_SECTION symbol must reference a real section, so reject one whose
> st_shndx is not a valid section index. Reserved indices are always
>> = SHN_LORESERVE, which exceeds sec_cnt, and the in-range case is
> already handled above, so a single sec_cnt bound closes the gap without
> affecting valid inputs.
> 
> Signed-off-by: Naveed Khan <naveed@digiscrypt.com>
> ---
> diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
> index 78f92c3929..8a93faa41d 100644
> --- a/tools/lib/bpf/linker.c
> +++ b/tools/lib/bpf/linker.c
> @@ -973,7 +973,7 @@ static int linker_sanity_check_elf_symtab(struct src_obj *obj, struct src_sec *s
>  			return -EINVAL;
>  		}
>  		if (sym_type == STT_SECTION) {
> -			if (sym->st_value != 0)
> +			if (sym->st_value != 0 || sym->st_shndx >= obj->sec_cnt)


As far as I can tell, this is only a problem when the ELF object is
corrupted. If you don't have a user report, or at least an example of
a normally compiled ELF object that can cause a crash, it's a NACK.

libbpf does not aim to be a safe parser for arbitrary malformed ELF.

pw-bot: cr


..An unsolicited piece of advice unrelated to the patch:

I checked your email on lore, and it appears you are a new contributor
trying to land similar patches across multiple subsystems. And I'm
pretty sure AI finds these bugs for you by inspecting code, and then
generates patches.

I can understand the motivation to get your name out, but this is not
a good way to do it.

Pick an area that interests you, or (if you don't have a preference)
pick something useful and/or neglected, like selftests. Read the
mailing list to understand what areas need work. Then figure out how
to actually improve the system, not just fix random unimportant
bugs. Come up with a strategy and start small. Use AI, but also try to
actually learn what's going on, don't just relay the output.

Good luck!


>  				return -EINVAL;
>  			continue;
>  		}


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-17  0:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13 13:16 [PATCH] libbpf: reject linker STT_SECTION symbols with out-of-range st_shndx Naveed Khan
2026-07-13 13:35 ` sashiko-bot
2026-07-17  0:53 ` Ihor Solodrai

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.