mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
libbpf: Don't assume SHT_GNU_verdef presence for SHT_GNU_versym section
Fix too eager assumption that SHT_GNU_verdef ELF section is going to be
present whenever binary has SHT_GNU_versym section. It seems like either
SHT_GNU_verdef or SHT_GNU_verneed can be used, so failing on missing
SHT_GNU_verdef actually breaks use cases in production.
One specific reported issue, which was used to manually test this fix,
was trying to attach to `readline` function in BASH binary.
Fixes: bb7fa09399 ("libbpf: Support symbol versioning for uprobe")
Reported-by: Liam Wisehart <liamwisehart@meta.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Manu Bretelle <chantr4@gmail.com>
Reviewed-by: Fangrui Song <maskray@google.com>
Acked-by: Hengqi Chen <hengqi.chen@gmail.com>
Link: https://lore.kernel.org/bpf/20231016182840.4033346-1-andrii@kernel.org
This commit is contained in:
committed by
Daniel Borkmann
parent
a3c2dd9648
commit
137df1189d
@@ -141,14 +141,15 @@ static int elf_sym_iter_new(struct elf_sym_iter *iter,
|
||||
iter->versyms = elf_getdata(scn, 0);
|
||||
|
||||
scn = elf_find_next_scn_by_type(elf, SHT_GNU_verdef, NULL);
|
||||
if (!scn) {
|
||||
pr_debug("elf: failed to find verdef ELF sections in '%s'\n", binary_path);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!gelf_getshdr(scn, &sh))
|
||||
return -EINVAL;
|
||||
iter->verdef_strtabidx = sh.sh_link;
|
||||
if (!scn)
|
||||
return 0;
|
||||
|
||||
iter->verdefs = elf_getdata(scn, 0);
|
||||
if (!iter->verdefs || !gelf_getshdr(scn, &sh)) {
|
||||
pr_warn("elf: failed to get verdef ELF section in '%s'\n", binary_path);
|
||||
return -EINVAL;
|
||||
}
|
||||
iter->verdef_strtabidx = sh.sh_link;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -199,6 +200,9 @@ static const char *elf_get_vername(struct elf_sym_iter *iter, int ver)
|
||||
GElf_Verdef verdef;
|
||||
int offset;
|
||||
|
||||
if (!iter->verdefs)
|
||||
return NULL;
|
||||
|
||||
offset = 0;
|
||||
while (gelf_getverdef(iter->verdefs, offset, &verdef)) {
|
||||
if (verdef.vd_ndx != ver) {
|
||||
|
||||
Reference in New Issue
Block a user