linux/arch/parisc/kernel
Mikulas Patocka 030f653078 parisc: fix crash with signals and alloca
I was debugging some crashes on parisc and I found out that there is a
crash possibility if a function using alloca is interrupted by a signal.
The reason for the crash is that the gcc alloca implementation leaves
garbage in the upper 32 bits of the sp register. This normally doesn't
matter (the upper bits are ignored because the PSW W-bit is clear),
however the signal delivery routine in the kernel uses full 64 bits of sp
and it fails with -EFAULT if the upper 32 bits are not zero.

I created this program that demonstrates the problem:

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <alloca.h>

static __attribute__((noinline,noclone)) void aa(int *size)
{
	void * volatile p = alloca(-*size);
	while (1) ;
}

static void handler(int sig)
{
	write(1, "signal delivered\n", 17);
	_exit(0);
}

int main(void)
{
	int size = -0x100;
	signal(SIGALRM, handler);
	alarm(1);
	aa(&size);
}

If you compile it with optimizations, it will crash.
The "aa" function has this disassembly:

000106a0 <aa>:
   106a0:       08 03 02 41     copy r3,r1
   106a4:       08 1e 02 43     copy sp,r3
   106a8:       6f c1 00 80     stw,ma r1,40(sp)
   106ac:       37 dc 3f c1     ldo -20(sp),ret0
   106b0:       0c 7c 12 90     stw ret0,8(r3)
   106b4:       0f 40 10 9c     ldw 0(r26),ret0		; ret0 = 0x00000000FFFFFF00
   106b8:       97 9c 00 7e     subi 3f,ret0,ret0	; ret0 = 0xFFFFFFFF0000013F
   106bc:       d7 80 1c 1a     depwi 0,31,6,ret0	; ret0 = 0xFFFFFFFF00000100
   106c0:       0b 9e 0a 1e     add,l sp,ret0,sp	;   sp = 0xFFFFFFFFxxxxxxxx
   106c4:       e8 1f 1f f7     b,l,n 106c4 <aa+0x24>,r0

This patch fixes the bug by truncating the "usp" variable to 32 bits.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Helge Deller <deller@gmx.de>
2021-09-01 21:52:02 +02:00
..
syscalls Kbuild updates for v5.14 2021-07-10 11:01:38 -07:00
.gitignore .gitignore: add SPDX License Identifier 2020-03-25 11:50:48 +01:00
alternative.c parisc: Refactor alternative code to accept multiple conditions 2020-04-05 22:50:40 +02:00
asm-offsets.c sched,arch: Remove unused TASK_STATE offsets 2021-06-18 11:43:09 +02:00
audit.c
cache.c parisc: Rewrite tlb flush threshold calculation 2020-10-15 08:10:39 +02:00
compat_audit.c
drivers.c dma-mapping: split <linux/dma-mapping.h> 2020-10-06 07:07:03 +02:00
entry.S parisc: Optimize per-pagetable spinlocks 2021-02-12 16:39:42 +01:00
firmware.c parisc: firmware: Update references to parisc website 2020-06-01 23:02:11 +02:00
ftrace.c ftrace: Have the callbacks receive a struct ftrace_regs instead of pt_regs 2020-11-13 12:14:55 -05:00
hardware.c parisc: hardware: Update references to parisc website 2020-06-01 23:02:39 +02:00
head.S mm: reorder includes after introduction of linux/pgtable.h 2020-06-09 09:39:13 -07:00
hpmc.S parisc: Fix IVT checksum calculation wrt HPMC 2021-02-12 16:31:42 +01:00
inventory.c parisc: Add qemu fw_cfg interface 2020-10-15 08:10:37 +02:00
irq.c Rework of the X86 irq stack handling: 2021-02-24 16:32:23 -08:00
jump_label.c
kexec_file.c parisc: add support for kexec_file_load() syscall 2019-09-08 15:41:46 +02:00
kexec.c parisc: add support for kexec_file_load() syscall 2019-09-08 15:41:46 +02:00
kgdb.c maccess: rename probe_kernel_{read,write} to copy_{from,to}_kernel_nofault 2020-06-17 10:57:41 -07:00
kprobes.c parisc: kprobes: Use generic kretprobe trampoline handler 2020-09-08 11:52:33 +02:00
Makefile parisc: fix compilation when KEXEC=n and KEXEC_FILE=y 2019-12-15 21:05:38 +01:00
module.c mm: don't include asm/pgtable.h if linux/mm.h is already included 2020-06-09 09:39:13 -07:00
pa7300lc.c
pacache.S mm: reorder includes after introduction of linux/pgtable.h 2020-06-09 09:39:13 -07:00
parisc_ksyms.c Revert "parisc: Add assembly implementations for memset, strlen, strcpy, strncpy and strcat" 2021-08-29 10:13:32 -07:00
patch.c parisc: add spinlock to patch function 2019-06-08 12:56:26 +02:00
pci-dma.c parisc: pci-dma: fix warning unused-function 2020-12-15 05:41:11 +01:00
pci.c parisc: Drop comments which are already in pci.h 2019-09-05 16:41:11 +02:00
pdc_chassis.c kernel.h: split out panic and oops helpers 2021-07-01 11:06:04 -07:00
pdc_cons.c tty: remove tty_operations::chars_in_buffer for non-buffering 2021-05-13 18:29:11 +02:00
pdt.c parisc: Report bad pages as HardwareCorrupted 2020-07-28 11:19:17 +02:00
perf_asm.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
perf_images.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
perf.c parisc/perf: open access for CAP_PERFMON privileged process 2020-04-16 12:19:08 -03:00
process.c sched: Introduce task_is_running() 2021-06-18 11:43:07 +02:00
processor.c parisc: Drop loops_per_jiffy from per_cpu struct 2020-11-11 14:57:30 +01:00
ptrace.c arch/parisc/kernel: remove duplicate include in ptrace 2021-03-04 09:12:29 +01:00
real2.S
relocate_kernel.S parisc: add kexec syscall support 2019-09-08 15:37:04 +02:00
setup.c parisc: Fix typo in setup.c 2021-05-03 15:08:59 +02:00
signal32.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
signal32.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
signal.c parisc: fix crash with signals and alloca 2021-09-01 21:52:02 +02:00
smp.c sched/core: Initialize the idle task with preemption disabled 2021-05-12 13:01:45 +02:00
stacktrace.c
sys_parisc32.c
sys_parisc.c parisc: Make user stack size configurable 2020-11-11 14:59:08 +01:00
syscall.S parisc: syscalls: switch to generic syscalltbl.sh 2021-04-27 09:43:56 +02:00
time.c parisc: use legacy_timer_tick 2020-10-30 21:57:05 +01:00
topology.c
traps.c parisc: Fix IVT checksum calculation wrt HPMC 2021-02-12 16:31:42 +01:00
unaligned.c Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2019-07-08 21:48:15 -07:00
unwind.c
vmlinux.lds.S vmlinux.lds.h: Split ELF_DETAILS from STABS_DEBUG 2020-09-01 09:50:35 +02:00