On 8/18/2026 5:06 PM, [email protected] wrote:
> This commit adds a linear search fallback for .eh_frame sections when
> the .eh_frame_hdr lacks a binary search table. It also introduces validation
> logic for the referenced .eh_frame section, guarded by a new config
> option EH_FRAME_LINEAR_SEARCH.

>> diff --git a/kernel/unwind/eh_frame.c b/kernel/unwind/eh_frame.c

>> @@ -590,6 +589,82 @@ static __always_inline int __find_fde(struct 
>> eh_frame_section *sec,
>>      return -EFAULT;
>>  }
>>  
>> +#ifdef CONFIG_EH_FRAME_LINEAR_SEARCH
>> +
>> +static __always_inline int __find_fde_lsearch(struct eh_frame_section *sec,
>> +                                          unsigned long ip,
>> +                                          struct eh_frame_fde *fde)
>> +{
>> +    unsigned long start = sec->eh_frame_start;
>> +    unsigned long vma_end = sec->eh_frame_vma_end;
>> +    unsigned long cur;
>> +    int ret;
>> +
>> +    /* Linear search through .eh_frame */
>> +    cur = start;
>> +    while (cur >= start && cur < vma_end) {
> 
> [Severity: High]
> Since the section header only provides the start address, this loop iterates
> all the way to vma_end. As noted in the commit message, many binaries lack
> a zero terminator.
> 
> If an unresolved IP is scanned, will this read past the actual section
> boundary into padding or other sections, return -EINVAL on garbage data, and
> subsequently cause the caller to permanently remove the section?

True.  I mentioned this in the patch description and notes that linear
.eh_frame search should better not be used.  I will drop this patch, as
the issue is now documented with RFC v1.
>> +#else /* !CONFIG_EH_FRAME_LINEAR_SEARCH */
>> +
>> +static __always_inline int __find_fde_lsearch(struct eh_frame_section *sec,
>> +                                          unsigned long ip,
>> +                                          struct eh_frame_fde *fde)
>> +{
>> +    return 0;
>> +}
> 
> [Severity: Critical]
> Does returning 0 here falsely indicate success when linear search is
> disabled?

My bad!  Got this wrong during rebase when splitting out linear search
into this separate patch.  Would need to return -ENOENT instead if this
should ever get picked up again.

> If a binary lacks a search table, __find_fde() will call this stub.
> Returning 0 causes the caller, eh_frame_find(), to proceed with an
> uninitialized fde stack variable:
> 
> kernel/unwind/eh_frame.c:eh_frame_find() {
>     struct eh_frame_fde fde;
>     ...
>     ret = __find_fde(sec, ip, &fde);
>     if (!ret)
>         ret = __find_frame_row(sec, &fde, ip, frame);
>     ...
> }
> 
> Could this lead to corrupted stack traces or arbitrary memory reads by
> consuming the uninitialized fde context? Should this return -ENOENT
> instead?

True.  See above.
>> +static int eh_frame_validate_section(struct eh_frame_section *sec)
>> +{
>> +    int ret;
>> +
>> +    /*
>> +     * Validate .eh_frame_hdr binary search table
>> +     * (incl. all referenced FDE and CIE in .eh_frame).
>> +     */
>> +    ret = eh_frame_validate_eh_frame_hdr(sec);
>> +    if (ret)
>> +            return ret;
>> +
>> +    /*
>> +     * Validate .eh_frame CIE and FDE.  Skip if linear search
>> +     * is disabled, as many .eh_frame sections lack a zero
>> +     * terminator and the section end if unknown.
>> +     */
>> +    if (IS_ENABLED(CONFIG_EH_FRAME_LINEAR_SEARCH)) {
>> +            ret = eh_frame_validate_eh_frame(sec);
>> +            if (ret)
>> +                    return ret;
>> +    }
> 
> [Severity: High]
> Does this unconditionally apply linear validation to all binaries when
> CONFIG_EH_FRAME_LINEAR_SEARCH is enabled, even if they already have a valid
> binary search table?

Yes, that was on purpose, as it would validate both .eh_frame_hdr and
.eh_frame sections.

> 
> If the binary lacks a zero terminator, eh_frame_validate_eh_frame() will
> read out of bounds up to vma_end, fail with -EINVAL, and reject the entire
> section.
> 
> Will this permanently break unwinding for valid binaries that were
> previously working fine via the binary search table?
> 
>> +
>> +    return 0;
>> +}
> 

Regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
[email protected] / [email protected]

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: 
Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: 
Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/


Reply via email to