Re: [RFC PATCH v1 12/25] unwind_user/eh_frame: Remove .eh_frame[_hdr] section on detected corruption
From: sashiko-bot@kernel.org
Date: 2026-08-18 15:10:59
Also in:
linux-s390
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Lockless maple tree traversal races with concurrent in-place updates due to missing MT_FLAGS_USE_RCU. --
--- Patch [12]: [RFC PATCH v1 12/25] unwind_user/eh_frame: Remove .eh_frame[_hdr] section on detected corruption ---commit 22bfd7679599379e32b650580760b87fb294aeb1 Author: Jens Remus [off-list ref] unwind_user/eh_frame: Remove .eh_frame[_hdr] section on detected corruption To avoid continued attempted use of a bad .eh_frame[_hdr] sections, remove them on demand when the first sign of corruption is detected. Based on Josh Poimboeuf's, Steven Rostedt's, and my unwind user sframe implementation.
quoted hunk ↗ jump to hunk
diff --git a/kernel/unwind/eh_frame.c b/kernel/unwind/eh_frame.c index 5ef8fef06a805..7657291324c06 100644 --- a/kernel/unwind/eh_frame.c +++ b/kernel/unwind/eh_frame.c@@ -1149,6 +1149,15 @@ int eh_frame_find(unsigned long ip, struct unwind_user_frame *frame) if (!ret) ret = __find_frame_row(sec, &fde, ip, frame); + /* + * Unregister .eh_frame[_hdr] in case of an error, + * e.g. EINVAL (corrupted) or EFAULT (inaccessible). + * Keep if ENOENT (not found) or EOPNOTSUPP (unsupported CFI). + */ + if (ret && (ret != -ENOENT && ret != -EOPNOTSUPP)) + if (eh_frame_remove_section(sec->eh_frame_hdr_start))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
Could this introduce a race condition with concurrent lockless readers?
If multiple threads encounter a corrupted section concurrently, this will
trigger eh_frame_remove_section(), which eventually calls mtree_erase() on
mm->eh_frame_mt:
kernel/unwind/eh_frame.c:__eh_frame_remove_section() {
...
if (!mtree_erase(&mm->eh_frame_mt, sec->text_start)) {
...
}
Because mm->eh_frame_mt is initialized in mm_init_eh_frame() without the
MT_FLAGS_USE_RCU flag:
kernel/fork.c:mm_init_eh_frame() {
...
mt_init(&mm->eh_frame_mt);
...
}
mtree_erase() will modify the tree nodes in-place instead of using RCU-safe
copy-on-write.
Concurrently, eh_frame_find() performs a lockless traversal using mtree_load(),
which only relies on standard RCU for protection:
kernel/unwind/eh_frame.c:eh_frame_find() {
...
sec = mtree_load(&mm->eh_frame_mt, ip);
...
}
Can concurrent readers observe torn state, freed nodes, or corrupted pivots
while the tree is being mutated in-place?
+ dbg("eh_frame_remove_section() failed\n");
+
return ret;
}-- Sashiko AI review · https://sashiko.dev/#/patchset/20260818144954.2320378-1-jremus@linux.ibm.com?part=12