Thread (67 messages) 67 messages, 3 authors, 2026-08-21

Re: [RFC PATCH v1 10/25] unwind_user/eh_frame: Detect .eh_frame_hdr sections in executables

From: sashiko-bot@kernel.org
Date: 2026-08-18 15:18:23
Also in: linux-s390

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Missing duplication of eh_frame_mt during fork() leaves child processes without stack unwind capability.
- [Medium] Executable segments with a trailing BSS section silently fail .eh_frame_hdr registration.
--
--- Patch [10]: [RFC PATCH v1 10/25] unwind_user/eh_frame: Detect .eh_frame_hdr sections in executables ---
commit e178ff4c7b227a1dcb3db08f8923210e443187ac
Author: Jens Remus [off-list ref]

unwind_user/eh_frame: Detect .eh_frame_hdr sections in executables

This commit modifies the ELF loader to automatically detect .eh_frame_hdr
sections during binary and interpreter loading. It associates these sections
with the mm_struct to support user-space stack unwinding.
When loading an ELF executable, automatically detect .eh_frame_hdr
sections and associate them with the mm_struct.
[Severity: High]
Are these eh_frame sections properly preserved for child processes during
fork()?

When a process forks, dup_mm() creates a new mm_struct and calls mm_init(),
which appears to initialize eh_frame_mt as an empty maple tree:

kernel/fork.c:mm_init_eh_frame() {
    ...
    mt_init(&mm->eh_frame_mt);
    ...
}

Is there any subsequent logic that duplicates the parent's eh_frame_mt
entries during dup_mm()? If not, won't child processes inherit correctly
duplicated VMAs but an empty eh_frame_mt, resulting in a complete loss of
stack unwinding capabilities for all children?
quoted hunk ↗ jump to hunk
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 16a56b6b3f6ca..8c1cdd8318c53 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
[ ... ]
quoted hunk ↗ jump to hunk
@@ -637,6 +638,23 @@ 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_eh_frame(const struct elf_phdr *text,
+			     const struct elf_phdr *eh_frame,
+			     unsigned long base_addr)
+{
+	unsigned long eh_frame_start, eh_frame_end,
+		      text_start, text_end;
+
+	eh_frame_start = base_addr + eh_frame->p_vaddr;
+	eh_frame_end   = eh_frame_start + eh_frame->p_memsz;
+
+	text_start   = base_addr + text->p_vaddr;
+	text_end     = text_start + text->p_memsz;
[Severity: Medium]
Will this silently fail to register .eh_frame_hdr for segments with a
trailing BSS section?

When an ELF executable segment has p_memsz > p_filesz crossing a page
boundary, the loader maps the file-backed portion and creates a separate
anonymous VMA for the BSS.

Because text_end is calculated using p_memsz, it may extend beyond the
file-backed VMA boundary. When this is passed to eh_frame_add_section(),
it uses vma_lookup() and checks if the entire segment resides in a single
VMA:

kernel/unwind/eh_frame.c:eh_frame_add_section() {
    ...
    if (!text_vma ||
        !(text_vma->vm_flags & VM_EXEC) ||
        text_end > text_vma->vm_end) {
        return -EINVAL;
    ...
}

Since the file-backed VMA ends before text_end in this scenario, won't the
text_end > text_vma->vm_end check fail and terminate registration?
quoted hunk ↗ jump to hunk
+
+	/* Ignore return value, eh_frame[_hdr] section isn't critical */
+	eh_frame_add_section(eh_frame_start, eh_frame_end, text_start, text_end);
+}
-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818144954.2320378-1-jremus@linux.ibm.com?part=10
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help