From nobody Sat Feb 7 17:17:56 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B172CC00140 for ; Mon, 15 Aug 2022 23:29:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344439AbiHOX3g (ORCPT ); Mon, 15 Aug 2022 19:29:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57036 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241882AbiHOXXJ (ORCPT ); Mon, 15 Aug 2022 19:23:09 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C21267391E; Mon, 15 Aug 2022 13:05:33 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D547360690; Mon, 15 Aug 2022 20:05:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DDED8C433D6; Mon, 15 Aug 2022 20:05:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660593932; bh=wzUTotmsOvyiM2qWLvIOatO2CoZfg/QgKijFCVNekYY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=osg9tDbXfB0v5yo4fxYDURkA1P2iTxpxDjkLyUNl5PtD17vALHM1Gcb0pGOIn3IfQ 1srGY6E75cEnyZO6YTyVm5XdyHqw2KW9S1H/Q7sY1bmWDz60KNOy/GZuyxyymeBMkA Nl1Yb2bfOijiLgVrzbNGKvf8HzRDDaVynvIIAI7A= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andrii Nakryiko , Daniel Borkmann , Riham Selim , Alan Maguire , Sasha Levin Subject: [PATCH 5.19 0350/1157] libbpf: Fix uprobe symbol file offset calculation logic Date: Mon, 15 Aug 2022 19:55:06 +0200 Message-Id: <20220815180453.716772247@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180439.416659447@linuxfoundation.org> References: <20220815180439.416659447@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Andrii Nakryiko [ Upstream commit fe92833524e368e59bba9c57e00f7359f133667f ] Fix libbpf's bpf_program__attach_uprobe() logic of determining function's *file offset* (which is what kernel is actually expecting) when attaching uprobe/uretprobe by function name. Previously calculation was determining virtual address offset relative to base load address, which (offset) is not always the same as file offset (though very frequently it is which is why this went unnoticed for a while). Fixes: 433966e3ae04 ("libbpf: Support function name-based attach uprobes") Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Cc: Riham Selim Cc: Alan Maguire Link: https://lore.kernel.org/bpf/20220606220143.3796908-1-andrii@kernel.org Signed-off-by: Sasha Levin --- tools/lib/bpf/libbpf.c | 63 +++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 526bd6cd84a0..b9245bf688fa 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -10983,43 +10983,6 @@ static int perf_event_uprobe_open_legacy(const cha= r *probe_name, bool retprobe, return pfd; } =20 -/* uprobes deal in relative offsets; subtract the base address associated = with - * the mapped binary. See Documentation/trace/uprobetracer.rst for more - * details. - */ -static long elf_find_relative_offset(const char *filename, Elf *elf, long = addr) -{ - size_t n; - int i; - - if (elf_getphdrnum(elf, &n)) { - pr_warn("elf: failed to find program headers for '%s': %s\n", filename, - elf_errmsg(-1)); - return -ENOENT; - } - - for (i =3D 0; i < n; i++) { - int seg_start, seg_end, seg_offset; - GElf_Phdr phdr; - - if (!gelf_getphdr(elf, i, &phdr)) { - pr_warn("elf: failed to get program header %d from '%s': %s\n", i, file= name, - elf_errmsg(-1)); - return -ENOENT; - } - if (phdr.p_type !=3D PT_LOAD || !(phdr.p_flags & PF_X)) - continue; - - seg_start =3D phdr.p_vaddr; - seg_end =3D seg_start + phdr.p_memsz; - seg_offset =3D phdr.p_offset; - if (addr >=3D seg_start && addr < seg_end) - return addr - seg_start + seg_offset; - } - pr_warn("elf: failed to find prog header containing 0x%lx in '%s'\n", add= r, filename); - return -ENOENT; -} - /* Return next ELF section of sh_type after scn, or first of that type if = scn is NULL. */ static Elf_Scn *elf_find_next_scn_by_type(Elf *elf, int sh_type, Elf_Scn *= scn) { @@ -11106,6 +11069,8 @@ static long elf_find_func_offset(const char *binary= _path, const char *name) for (idx =3D 0; idx < nr_syms; idx++) { int curr_bind; GElf_Sym sym; + Elf_Scn *sym_scn; + GElf_Shdr sym_sh; =20 if (!gelf_getsym(symbols, idx, &sym)) continue; @@ -11143,12 +11108,28 @@ static long elf_find_func_offset(const char *bina= ry_path, const char *name) continue; } } - ret =3D sym.st_value; + + /* Transform symbol's virtual address (absolute for + * binaries and relative for shared libs) into file + * offset, which is what kernel is expecting for + * uprobe/uretprobe attachment. + * See Documentation/trace/uprobetracer.rst for more + * details. + * This is done by looking up symbol's containing + * section's header and using it's virtual address + * (sh_addr) and corresponding file offset (sh_offset) + * to transform sym.st_value (virtual address) into + * desired final file offset. + */ + sym_scn =3D elf_getscn(elf, sym.st_shndx); + if (!sym_scn) + continue; + if (!gelf_getshdr(sym_scn, &sym_sh)) + continue; + + ret =3D sym.st_value - sym_sh.sh_addr + sym_sh.sh_offset; last_bind =3D curr_bind; } - /* For binaries that are not shared libraries, we need relative offset */ - if (ret > 0 && !is_shared_lib) - ret =3D elf_find_relative_offset(binary_path, elf, ret); if (ret > 0) break; } --=20 2.35.1