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