From nobody Wed Jan 22 11:34:46 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22AB61C5F39; Wed, 22 Jan 2025 02:32:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737513133; cv=none; b=MHLe6SXuv6O2qOLRCczFJv6OuE4cJ7KRSYrI6JY+ZxA7hcG7OMMF2WSGGtwrSUVsSkWhwn7cUluXb3ddI6gqMnb2pZLu/THFHkXJ1ZBn19azz38Q2HY0Se5vBDXaNsTWRpovHAsrVSviY50BneO/W0wshk5o8++RmJflj1BD470= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737513133; c=relaxed/simple; bh=0lbd2qu1rhFADP15o4ZX88OlHxQN+oJb9mzbgZWD9R0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RVgJm1y2YLzWpW7TRgz9KVIi6T03zWixSLOalh1rPZ+3oz/Yp1Z4E7lsX2iNF9jIO1c6d3xd3/gy1VvvtagdW+nXTbBEFbdvZj+r1ttPClKZ0tR9AGgL/Msl2wVsVZrqx5pIXV1DsQbWJYRMkU3w93iD6s0+Dd8xK7QzkHkH4Y4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=h7yFrwy5; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="h7yFrwy5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A4F8C4CEE8; Wed, 22 Jan 2025 02:32:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1737513133; bh=0lbd2qu1rhFADP15o4ZX88OlHxQN+oJb9mzbgZWD9R0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h7yFrwy5IU+2pveZa193HkI+Q65/KCeBe0Eot9OcmGVsWCL0P4hNoGRX667uTCEUP VxBxVG0UI7lWdra4csT6HClAtawbjtJTX3wXe6TiyVoS4qdWj8nFy4SBL5VfWZrT1K pJVlQWyITUamM3Lsnv0nBXQwWrWlw0IVQdxONrHwjvkUChqrxonPZ6NT/Tu/enNyAR cyIBu5SX5Hq4C+71rbwh1eeeBXDd31ArXFEGbeq/hGgLJQKTDfruBlg++UmgFnIz1J a5HcS+UTP1m8e6UM+WXahPi1jD4M+O2U7iP1fP9xapOnL2e/9Bfc2z6R6QKkv5EaBQ duMygIL1T/1jw== From: Josh Poimboeuf To: x86@kernel.org Cc: Peter Zijlstra , Steven Rostedt , Ingo Molnar , Arnaldo Carvalho de Melo , linux-kernel@vger.kernel.org, Indu Bhagat , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , linux-perf-users@vger.kernel.org, Mark Brown , linux-toolchains@vger.kernel.org, Jordan Rome , Sam James , linux-trace-kernel@vger.kernel.org, Andrii Nakryiko , Jens Remus , Mathieu Desnoyers , Florian Weimer , Andy Lutomirski , Masami Hiramatsu , Weinan Liu Subject: [PATCH v4 20/39] unwind_user/sframe: Detect .sframe sections in executables Date: Tue, 21 Jan 2025 18:31:12 -0800 Message-ID: <3d4d6fc48a766666b82f415ebb4aa8cc435f30ae.1737511963.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When loading an ELF executable, automatically detect an .sframe section and associate it with the mm_struct. Signed-off-by: Josh Poimboeuf --- fs/binfmt_elf.c | 49 +++++++++++++++++++++++++++++++++++++--- include/uapi/linux/elf.h | 1 + 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 106f0e8af177..90cd745e5bd6 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include =20 @@ -629,6 +630,21 @@ static inline int make_prot(u32 p_flags, struct arch_e= lf_state *arch_state, return arch_elf_adjust_prot(prot, arch_state, has_interp, is_interp); } =20 +static void elf_add_sframe(struct elf_phdr *text, struct elf_phdr *sframe, + unsigned long base_addr) +{ + unsigned long sframe_start, sframe_end, text_start, text_end; + + sframe_start =3D base_addr + sframe->p_vaddr; + sframe_end =3D sframe_start + sframe->p_memsz; + + text_start =3D base_addr + text->p_vaddr; + text_end =3D text_start + text->p_memsz; + + /* Ignore return value, sframe section isn't critical */ + sframe_add_section(sframe_start, sframe_end, text_start, text_end); +} + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have @@ -639,7 +655,7 @@ static unsigned long load_elf_interp(struct elfhdr *int= erp_elf_ex, unsigned long no_base, struct elf_phdr *interp_elf_phdata, struct arch_elf_state *arch_state) { - struct elf_phdr *eppnt; + struct elf_phdr *eppnt, *sframe_phdr =3D NULL; unsigned long load_addr =3D 0; int load_addr_set =3D 0; unsigned long error =3D ~0UL; @@ -665,7 +681,8 @@ static unsigned long load_elf_interp(struct elfhdr *int= erp_elf_ex, =20 eppnt =3D interp_elf_phdata; for (i =3D 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { - if (eppnt->p_type =3D=3D PT_LOAD) { + switch (eppnt->p_type) { + case PT_LOAD: { int elf_type =3D MAP_PRIVATE; int elf_prot =3D make_prot(eppnt->p_flags, arch_state, true, true); @@ -704,6 +721,20 @@ static unsigned long load_elf_interp(struct elfhdr *in= terp_elf_ex, error =3D -ENOMEM; goto out; } + break; + } + case PT_GNU_SFRAME: + sframe_phdr =3D eppnt; + break; + } + } + + if (sframe_phdr) { + eppnt =3D interp_elf_phdata; + for (i =3D 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { + if (eppnt->p_flags & PF_X) { + elf_add_sframe(eppnt, sframe_phdr, load_addr); + } } } =20 @@ -829,7 +860,7 @@ static int load_elf_binary(struct linux_binprm *bprm) int first_pt_load =3D 1; unsigned long error; struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata =3D NULL; - struct elf_phdr *elf_property_phdata =3D NULL; + struct elf_phdr *elf_property_phdata =3D NULL, *sframe_phdr =3D NULL; unsigned long elf_brk; int retval, i; unsigned long elf_entry; @@ -937,6 +968,10 @@ static int load_elf_binary(struct linux_binprm *bprm) executable_stack =3D EXSTACK_DISABLE_X; break; =20 + case PT_GNU_SFRAME: + sframe_phdr =3D elf_ppnt; + break; + case PT_LOPROC ... PT_HIPROC: retval =3D arch_elf_pt_proc(elf_ex, elf_ppnt, bprm->file, false, @@ -1227,6 +1262,14 @@ static int load_elf_binary(struct linux_binprm *bprm) elf_brk =3D k; } =20 + if (sframe_phdr) { + for (i =3D 0, elf_ppnt =3D elf_phdata; + i < elf_ex->e_phnum; i++, elf_ppnt++) { + if ((elf_ppnt->p_flags & PF_X)) + elf_add_sframe(elf_ppnt, sframe_phdr, load_bias); + } + } + e_entry =3D elf_ex->e_entry + load_bias; phdr_addr +=3D load_bias; elf_brk +=3D load_bias; diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index b44069d29cec..026978cddc2e 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -39,6 +39,7 @@ typedef __s64 Elf64_Sxword; #define PT_GNU_STACK (PT_LOOS + 0x474e551) #define PT_GNU_RELRO (PT_LOOS + 0x474e552) #define PT_GNU_PROPERTY (PT_LOOS + 0x474e553) +#define PT_GNU_SFRAME (PT_LOOS + 0x474e554) =20 =20 /* ARM MTE memory tag segment type */ --=20 2.48.1