From mboxrd@z Thu Jan 1 00:00:00 1970 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 5FDE72FD7CE; Wed, 27 Aug 2025 20:24:22 +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=1756326262; cv=none; b=MlJr0OyGh/Lt7kMmq1cES2iipoRTl25+zm3rn30kXi6KpCr8W2LyChVgGbGzDsyMV240n8q4nucDzCIp6SiYipLksv8Us8JtOMGX7pQ83cxnBZr6kWdwJ3t2Agxq5493GndGWdKo4Nf1hHM9zLzJZx47ccT5P4RxZWSWnO5wD7E= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756326262; c=relaxed/simple; bh=ZSB0DnLzbKO8PCtsd2VxzkydgfL0SwzNGhpgsWTugOw=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=N5rzmQ3QcQb5fEADjnD6MYgenLdExOEwrPlhYBVNbVRqhiThqzGQtOM3+f7DgEOcAVrRle3QarUn6SpUiz10LUSsHTctLPTMy+oICffbXQL1ipQYhwhgnWEA1NAQhXLc4AKW8rHBY8iIvjVynkto/WWz4+bc+8OFwhKYRg5bUJk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ap9/YJjp; 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="Ap9/YJjp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36C2FC4CEF7; Wed, 27 Aug 2025 20:24:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1756326262; bh=ZSB0DnLzbKO8PCtsd2VxzkydgfL0SwzNGhpgsWTugOw=; h=Date:From:To:Cc:Subject:References:From; b=Ap9/YJjpWNRXq+ka9fcI3c2Tyv5uvcrw3lK6BOUtwmTW4GhtV1HMh/zj4UyUfX6V1 aopmKgmt+vQcwsLpafeUMP9X1GAwO3NzCzM0RT28nqqOqhog5Lb/VA87RmdcfCcEQ9 pvlh0R4efmUNi/B1JJNlRho0LYgVWmP28SdshU6Mw10cSISc4BOG1J/+jgjCp2i1ZU Z9HBh05sbCmPx+Mqy2vPDREXxcqWtzme6G8ygBjeZhwEwautl/nz/0LWgeHA4sbqgA kCTbCu9CjYHCf3n2M5Y3wYOWNmFm61+L5WAe78Mbf+FsqpMu5JY+8RUjyNPanqYh2y gWSoBrvCChLOQ== Received: from rostedt by gandalf with local (Exim 4.98.2) (envelope-from ) id 1urMhF-00000003kyL-0OqI; Wed, 27 Aug 2025 16:24:41 -0400 Message-ID: <20250827202440.946751792@kernel.org> User-Agent: quilt/0.68 Date: Wed, 27 Aug 2025 16:15:53 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, bpf@vger.kernel.org, x86@kernel.org Cc: Masami Hiramatsu , Mathieu Desnoyers , Josh Poimboeuf , Peter Zijlstra , Ingo Molnar , Jiri Olsa , Arnaldo Carvalho de Melo , Namhyung Kim , Thomas Gleixner , Andrii Nakryiko , Indu Bhagat , "Jose E. Marchesi" , Beau Belgrave , Jens Remus , Linus Torvalds , Andrew Morton , Florian Weimer , Sam James , Kees Cook , "Carlos O'Donell" , linux-mm@kvack.org Subject: [PATCH v10 05/11] unwind_user/sframe: Detect .sframe sections in executables References: <20250827201548.448472904@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 From: Josh Poimboeuf When loading an ELF executable, automatically detect an .sframe section and associate it with the mm_struct. Cc: linux-mm@kvack.org Signed-off-by: Josh Poimboeuf Signed-off-by: Steven Rostedt (Google) --- 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 264fba0d44bd..1fd7623cf9a5 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -622,6 +623,21 @@ static inline int make_prot(u32 p_flags, struct arch_elf_state *arch_state, return arch_elf_adjust_prot(prot, arch_state, has_interp, is_interp); } +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 = base_addr + sframe->p_vaddr; + sframe_end = sframe_start + sframe->p_memsz; + + text_start = base_addr + text->p_vaddr; + text_end = 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 @@ -632,7 +648,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_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 = NULL; unsigned long load_addr = 0; int load_addr_set = 0; unsigned long error = ~0UL; @@ -658,7 +674,8 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, eppnt = interp_elf_phdata; for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { - if (eppnt->p_type == PT_LOAD) { + switch (eppnt->p_type) { + case PT_LOAD: { int elf_type = MAP_PRIVATE; int elf_prot = make_prot(eppnt->p_flags, arch_state, true, true); @@ -697,6 +714,20 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, error = -ENOMEM; goto out; } + break; + } + case PT_GNU_SFRAME: + sframe_phdr = eppnt; + break; + } + } + + if (sframe_phdr) { + eppnt = interp_elf_phdata; + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { + if (eppnt->p_flags & PF_X) { + elf_add_sframe(eppnt, sframe_phdr, load_addr); + } } } @@ -821,7 +852,7 @@ static int load_elf_binary(struct linux_binprm *bprm) int first_pt_load = 1; unsigned long error; struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; - struct elf_phdr *elf_property_phdata = NULL; + struct elf_phdr *elf_property_phdata = NULL, *sframe_phdr = NULL; unsigned long elf_brk; bool brk_moved = false; int retval, i; @@ -930,6 +961,10 @@ static int load_elf_binary(struct linux_binprm *bprm) executable_stack = EXSTACK_DISABLE_X; break; + case PT_GNU_SFRAME: + sframe_phdr = elf_ppnt; + break; + case PT_LOPROC ... PT_HIPROC: retval = 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 = k; } + if (sframe_phdr) { + for (i = 0, elf_ppnt = 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 = elf_ex->e_entry + load_bias; phdr_addr += load_bias; elf_brk += load_bias; diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 819ded2d39de..92c16c94fca8 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -41,6 +41,7 @@ typedef __u16 Elf64_Versym; #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) /* ARM MTE memory tag segment type */ -- 2.50.1