Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Integer overflow in binary search table size calculation allows bypassing `.eh_frame_hdr` bounds check.
- [Medium] The `read_encoded_pointer` function incorrectly overwrites the computed base address when handling the `DW_EH_PE_absptr` format combined with relative application flags.
--
--- Patch [7]: [RFC PATCH v1 07/25] unwind_user/eh_frame: Add support for reading .eh_frame_hdr section ---
commit 0ca4af16fa2ddbd53ffc639d7ba44b189726700c
Author: Jens Remus <[email protected]>
unwind_user/eh_frame: Add support for reading .eh_frame_hdr section
This commit adds basic infrastructure for reading the .eh_frame_hdr
section from userspace in preparation for .eh_frame based stack unwinding.
> diff --git a/kernel/unwind/eh_frame.c b/kernel/unwind/eh_frame.c
> new file mode 100644
> index 0000000000000..8d2b638145bd4
> --- /dev/null
> +++ b/kernel/unwind/eh_frame.c
[ ... ]
> +static __always_inline int read_encoded_pointer(struct eh_frame_section *sec,
> + unsigned long *addr,
> + unsigned long end,
> + u8 encoding,
> + unsigned long *value)
> +{
> + unsigned long cur = *addr;
> + u8 format = DW_EH_PE_format(encoding);
> + u8 application = DW_EH_PE_application(encoding);
> + unsigned long result = 0;
> + int ret;
> +
> + if (encoding == DW_EH_PE_omit)
> + return -EINVAL;
> +
> + /* Determine base address based on application */
> + switch (application) {
> + case 0:
> + /* Absolute */
> + break;
> + case DW_EH_PE_pcrel:
> + result = *addr;
> + break;
> + case DW_EH_PE_datarel:
> + result = sec->eh_frame_hdr_start;
> + break;
> + case DW_EH_PE_textrel:
> + result = sec->text_start;
> + break;
> + case DW_EH_PE_funcrel:
> + case DW_EH_PE_aligned:
> + return -EOPNOTSUPP;
> + default:
> + return -EINVAL;
> + }
> +
> + /* Read value based on format */
> + switch (format) {
> + case DW_EH_PE_absptr:
> + UNSAFE_GET_USER_INC(result, cur, end, Efault);
> + break;
[Severity: Medium]
Does this overwrite the base address that was just computed for relative
encodings?
When handling DW_EH_PE_absptr in combination with relative application flags
like DW_EH_PE_pcrel, the base address is stored in the result variable above.
However, UNSAFE_GET_USER_INC directly assigns the read value to result
instead of adding it, which will discard the base address.
Should this read into a temporary variable and add it to result, similar to
how the other formats are handled?
> + case DW_EH_PE_uleb128: {
> + unsigned long tmp;
> + ret = read_uleb128(&cur, end, &tmp);
> + if (ret)
> + return ret;
> + result += tmp;
> + break;
> + }
[ ... ]
> +static int eh_frame_read_header(struct eh_frame_section *sec)
> +{
> + struct mm_struct *mm = current->mm;
> + void __user *eh_frame_hdr = (void __user *)sec->eh_frame_hdr_start;
> + unsigned long cur = sec->eh_frame_hdr_start, end = sec->eh_frame_hdr_end;
> + unsigned long eh_frame_start, eh_frame_vma_end, table_start, table_end;
> + u8 version, eh_frame_ptr_enc, fde_count_enc, table_enc;
> + unsigned long fde_count;
> + int entry_size;
> + int ret;
[ ... ]
> + /* Read FDE count */
> + ret = read_encoded_pointer(sec, &cur, end,
> + fde_count_enc, &fde_count);
> + if (ret)
> + return ret;
> +
> + /* Determine binary search table start and end */
> + table_start = cur;
> + entry_size = 2 * encoded_pointer_size(table_enc);
> + if (!entry_size)
> + return -EINVAL;
> + table_end = table_start + fde_count * entry_size;
> + if (table_end > sec->eh_frame_hdr_end)
> + return -EINVAL;
[Severity: Medium]
Can a maliciously large fde_count cause an integer overflow here?
Since fde_count is parsed from the untrusted user eh_frame_hdr section,
the multiplication of fde_count * entry_size could wrap around to a small
positive value.
This would bypass the bounds check against sec->eh_frame_hdr_end and
potentially allow the kernel to trust an arbitrarily large fde_count,
leading to out-of-bounds kernel memory reads when performing binary searches.
Would it be safer to use check_mul_overflow() and check_add_overflow() for
these bounds calculations?
> + }
> +
> +end:
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=7
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.