All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jens Remus" <jremus@linux.ibm.com>
Cc: "Heiko Carstens" <hca@linux.ibm.com>,
	"Alexander Gordeev" <agordeev@linux.ibm.com>,
	linux-trace-kernel@vger.kernel.org,
	"Christian Borntraeger" <borntraeger@linux.ibm.com>,
	linux-s390@vger.kernel.org, "Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [RFC PATCH v2 07/24] unwind_user/eh_frame: Add support for reading .eh_frame_hdr section
Date: Fri, 21 Aug 2026 20:06:15 +0000	[thread overview]
Message-ID: <20260821200615.85E461F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260821195259.2688377-8-jremus@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Incorrect pointer size assumption for 32-bit compat tasks using DW_EH_PE_absptr encoding.
- [High] Bypassing speculative execution pointer masking by using an unmasked pointer within a `scoped_user_read_access_size` block.
- [Low] Mixing goto-based cleanup labels and scoped_guard declarations in the same function.
--

--- Patch [7]: [RFC PATCH v2 07/24] unwind_user/eh_frame: Add support for reading .eh_frame_hdr section ---
commit d29ad7450daa52f7e2ed07991186d7ccf95beadb
Author: Jens Remus <jremus@linux.ibm.com>

unwind_user/eh_frame: Add support for reading .eh_frame_hdr section
    
In preparation for unwinding user space stacks with .eh_frame, add
basic unwind user eh_frame infrastructure and support for reading the
.eh_frame_hdr section.

> diff --git a/kernel/unwind/eh_frame.c b/kernel/unwind/eh_frame.c
> new file mode 100644
> index 0000000000000..f25a0923e315b
> --- /dev/null
> +++ b/kernel/unwind/eh_frame.c
> @@ -0,0 +1,366 @@

[ ... ]

> +static __always_inline int encoded_pointer_size(u8 encoding)
> +{
> +	u8 format = DW_EH_PE_format(encoding);
> +
> +	switch (format) {
> +	case DW_EH_PE_absptr:
> +		return sizeof(unsigned long);

[Severity: High]
Does hardcoding sizeof(unsigned long) here cause issues for 32-bit compat
tasks?

If a 64-bit kernel is profiling a 32-bit application, DW_EH_PE_absptr is
expected to match the application's native 4-byte pointer size. Using
sizeof(unsigned long) means the kernel will read 8 bytes, which could
consume too much data and misalign the current pointer for the remainder
of the unwinding process.

> +	case DW_EH_PE_udata2:
> +	case DW_EH_PE_sdata2:
> +		return 2;

[ ... ]

> +static __always_inline int read_encoded_pointer(struct eh_frame_section *sec,
> +						unsigned long *addr,
> +						unsigned long end,
> +						u8 encoding,
> +						unsigned long *value)
> +{

[ ... ]

> +	/* Read value based on format */
> +	switch (format) {
> +	case DW_EH_PE_absptr: {
> +		unsigned long tmp;
> +		UNSAFE_GET_USER_INC(tmp, cur, end, Efault);
> +		result += tmp;
> +		break;
> +	}

[Severity: High]
Will this also read 8 bytes instead of 4 for a 32-bit task?

Similar to encoded_pointer_size(), this reads a full unsigned long for an
absolute pointer. If this is a 64-bit kernel unwinding a 32-bit compat
application, it seems this might read past the intended data boundaries
and corrupt the address parsing.

> +	case DW_EH_PE_uleb128: {
> +		unsigned long tmp;

[ ... ]

> +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;

[ ... ]

> +	scoped_user_read_access_size(eh_frame_hdr, end - sec->eh_frame_hdr_start,
> +				     Efault) {
> +		/* Read version */
> +		UNSAFE_GET_USER_INC(version, cur, end, Efault);

[Severity: High]
Does this bypass the speculative execution pointer masking provided by
scoped_user_read_access_size()?

The block masks the eh_frame_hdr pointer, but inside the block,
UNSAFE_GET_USER_INC() reads from the unmasked unsigned long cur variable:

#define UNSAFE_GET_USER_INC(to, from, end, label)
...
	unsafe_get_user(__to, (typeof(to) __user *)from, label);

Since cur is passed to unsafe_get_user() without being masked, it appears
this defeats the Spectre V1 mitigation for architectures relying on
can_do_masked_user_access().

> +		if (version != 1)
> +			return -EINVAL;

[ ... ]

> +int eh_frame_add_section(unsigned long eh_frame_hdr_start,
> +			 unsigned long eh_frame_hdr_end,
> +			 unsigned long text_start,
> +			 unsigned long text_end)
> +{
> +	struct mm_struct *mm = current->mm;
> +	struct eh_frame_section *sec;
> +	int ret;

[ ... ]

> +	scoped_guard(mmap_read_lock, mm) {
> +		struct vm_area_struct *eh_frame_hdr_vma, *text_vma;
> +
> +		eh_frame_hdr_vma = vma_lookup(mm, eh_frame_hdr_start);

[ ... ]

> +	ret = eh_frame_read_header(sec);
> +	if (ret)
> +		goto err_free;
> +
> +	/* TODO nowhere to store it yet - just free it and return an error */
> +	ret = -ENOSYS;
> +
> +err_free:
> +	free_section(sec);
> +	return ret;
> +}

[Severity: Low]
This isn't a bug, but should this function avoid mixing scoped_guard() and
goto-based error handling?

The kernel cleanup guidelines recommend either fully converting to
scope-based cleanup (for example, using __free() for the sec allocation)
or strictly using goto-based cleanups without scoped_guard(). Mixing them
in the same function can create confusing ownership semantics.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260821195259.2688377-1-jremus@linux.ibm.com?part=7

  reply	other threads:[~2026-08-21 20:06 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 19:52 [RFC PATCH v2 00/24] unwind_user: Implement .eh_frame handling Jens Remus
2026-08-21 19:52 ` [RFC PATCH v2 01/24] unwind_user: Add generic and arch-specific headers to MAINTAINERS Jens Remus
2026-08-21 19:52 ` [RFC PATCH v2 02/24] unwind_user: Stop when reaching an outermost frame Jens Remus
2026-08-21 20:00   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 03/24] unwind_user: Enable archs that pass RA in a register Jens Remus
2026-08-21 20:02   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 04/24] unwind_user: Flexible FP/RA recovery rules Jens Remus
2026-08-21 20:03   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 05/24] unwind_user: Flexible CFA " Jens Remus
2026-08-21 20:03   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 06/24] unwind_user: Enable archs that define CFA = SP_callsite + offset Jens Remus
2026-08-21 20:03   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 07/24] unwind_user/eh_frame: Add support for reading .eh_frame_hdr section Jens Remus
2026-08-21 20:06   ` sashiko-bot [this message]
2026-08-21 19:52 ` [RFC PATCH v2 08/24] unwind_user/eh_frame: Store .eh_frame_hdr section data in per-mm maple tree Jens Remus
2026-08-21 20:13   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 09/24] unwind_user/eh_frame: Add support for reading .eh_frame section Jens Remus
2026-08-21 20:16   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 10/24] unwind_user/eh_frame: Detect .eh_frame_hdr sections in executables Jens Remus
2026-08-21 20:10   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 11/24] unwind_user/eh_frame: Wire up unwind_user to eh_frame Jens Remus
2026-08-21 20:07   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 12/24] unwind_user/eh_frame: Remove .eh_frame[_hdr] section on detected corruption Jens Remus
2026-08-21 20:18   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 13/24] unwind_user/eh_frame: Show file name in debug output Jens Remus
2026-08-21 20:06   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 14/24] unwind_user/eh_frame: Add .eh_frame[_hdr] validation option Jens Remus
2026-08-21 20:10   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 15/24] unwind_user/eh_frame: Duplicate registered .eh_frame[_hdr] section data on clone/fork Jens Remus
2026-08-21 20:09   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 16/24] unwind_user/eh_frame: Ignore DW_CFA_GNU_args_size Jens Remus
2026-08-21 20:03   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 17/24] unwind_user/eh_frame: Add support for DWARF expressions Jens Remus
2026-08-21 20:18   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 18/24] x86/uaccess: Add unsafe_copy_from_user() implementation Jens Remus
2026-08-21 20:11   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 19/24] unwind_user/eh_frame/x86: Enable eh_frame unwinding on x86 Jens Remus
2026-08-21 20:16   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 20/24] unwind_user/eh_frame/x86: Handle PLT expressions Jens Remus
2026-08-21 20:17   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 21/24] unwind_user/eh_frame/x86: Handle DRAP expressions Jens Remus
2026-08-21 20:15   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 22/24] s390/ptrace: Provide frame_pointer() Jens Remus
2026-08-21 20:07   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 23/24] unwind_user/eh_frame/s390: Enable eh_frame unwinding on s390 Jens Remus
2026-08-21 20:15   ` sashiko-bot
2026-08-21 19:52 ` [RFC PATCH v2 24/24] unwind_user/eh_frame: Add prctl() interface for (un)registering .eh_frame_hdr sections Jens Remus
2026-08-21 20:22   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260821200615.85E461F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=jremus@linux.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.