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 <[email protected]>

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.

> 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/[email protected]?part=12

Reply via email to