kernel_optimize_test/arch/parisc
Mikulas Patocka 7a5756e905 parisc: fix crash with signals and alloca
commit 030f653078316a9cc9ca6bd1b0234dcf858be35d upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-09-18 13:40:35 +02:00
..
boot vmlinux.lds.h: Split ELF_DETAILS from STABS_DEBUG 2020-09-01 09:50:35 +02:00
configs parisc: disable CONFIG_IDE in defconfigs 2020-10-15 08:10:38 +02:00
include Revert "parisc: Add assembly implementations for memset, strlen, strcpy, strncpy and strcat" 2021-09-03 10:09:31 +02:00
kernel parisc: fix crash with signals and alloca 2021-09-18 13:40:35 +02:00
lib Revert "parisc: Add assembly implementations for memset, strlen, strcpy, strncpy and strcat" 2021-09-03 10:09:31 +02:00
math-emu Makefile: Convert -Wimplicit-fallthrough=3 to just -Wimplicit-fallthrough for clang 2019-08-10 12:45:37 -07:00
mm treewide: Convert macro and uses of __section(foo) to __section("foo") 2020-10-25 14:51:49 -07:00
oprofile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
defpalo.conf
install.sh parisc: Install vmlinuz instead of zImage file 2020-10-15 08:10:39 +02:00
Kconfig parisc: Enable -mlong-calls gcc option with CONFIG_COMPILE_TEST 2021-03-11 14:17:21 +01:00
Kconfig.debug Kconfig: consolidate the "Kernel hacking" menu 2018-08-02 08:06:48 +09:00
Makefile kbuild: fix broken builds because of GZIP,BZIP2,LZOP variables 2020-06-11 20:14:41 +09:00
nm