Re: [PATCH v3 09/19] unwind: Introduce sframe user space unwinding

Jens Remus <[email protected]>
Newsgroups org.kernel.vger.linux-toolchains,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users
Organization IBM Deutschland Research & Development GmbH
Message-ID <[email protected]>
On 28.10.2024 22:47, Josh Poimboeuf wrote:
...
> diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c
...
> +static int find_fde(struct sframe_section *sec, unsigned long ip,
> +		    struct sframe_fde *fde)
> +{
> +	struct sframe_fde __user *first, *last, *found = NULL;
> +	u32 ip_off, func_off_low = 0, func_off_high = -1;
> +
> +	ip_off = ip - sec->sframe_addr;
> +
> +	first = (void __user *)sec->fdes_addr;
> +	last = first + sec->fdes_nr;

Could it be that this needs to be:

	last = first + sec->fdes_nr - 1;

> +	while (first <= last) {
> +		struct sframe_fde __user *mid;
> +		u32 func_off;
> +
> +		mid = first + ((last - first) / 2);
> +
> +		if (get_user(func_off, (s32 __user *)mid))
> +			return -EFAULT;
> +
> +		if (ip_off >= func_off) {
> +			/* validate sort order */
> +			if (func_off < func_off_low)
> +				return -EINVAL;

Otherwise I run into this when the IP is within the function whose FDE 
is the last one in the .sframe section:

find_fde: IP=0x000000000110fbcc: ERROR: func_off < func_off_low 
(func_off=196608, func_off_low=4294224904)

110fbcc dump_sframe+0x2ec (/opt/binutils-sframe2/bin/objdump)

func idx [2275]: pc = 0x110f8e0, size = 3310 bytes <dump_sframe>
STARTPC         CFA       FP        RA           INFO
000000000110f8e0  sp+160    u         u            (1*1B)
000000000110f8e6  sp+160    c-72      c-48         (3*1B)
000000000110f8f6  sp+632    c-72      c-48         (3*1B)
000000000110fa82  sp+160    u         u            (1*1B)
000000000110fa88  sp+632    c-72      c-48         (3*1B)
0000000001110486  sp+160    u         u            (1*1B)
000000000111048c  sp+632    c-72      c-48         (3*1B)
0000000001110574  sp+160    u         u            (1*1B)
000000000111057a  sp+632    c-72      c-48         (3*1B)

> +
> +			func_off_low = func_off;
> +
> +			found = mid;
> +			first = mid + 1;
> +		} else {
> +			/* validate sort order */
> +			if (func_off > func_off_high)
> +				return -EINVAL;
> +
> +			func_off_high = func_off;
> +
> +			last = mid - 1;
> +		}
> +	}
> +
> +	if (!found)
> +		return -EINVAL;
> +
> +	if (copy_from_user(fde, found, sizeof(*fde)))
> +		return -EFAULT;
> +
> +	/* check for gaps */
> +	if (ip_off < fde->start_addr || ip_off >= fde->start_addr + fde->size)
> +		return -EINVAL;
> +
> +	return 0;
> +}

Thanks and regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303) and z/VSE Support
+49-7031-16-1128 Office
[email protected]

IBM

IBM Deutschland Research & Development GmbH; Vorsitzender des 
Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der 
Gesellschaft: Böblingen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/
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.