2.5.48 s390 (7/16): uaccess bug.
PATCH 1/1 2.5.48 s390 (7/16): uaccess bug.
Don't rely on lowcore information in __copy_{from,to}_user_asm. Fix compile for peculiar get_user() usage in drivers/scsi/scsi_ioctl.c
arch/s390/lib/uaccess.S +52 -32
@@ -1,9 +1,9 @@ /* * arch/s390/lib/uaccess.S - * fixup routines for copy_{from|to}_user functions. + * __copy_{from|to}_user functions. * * s390 - * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation * Authors(s): Martin Schwidefsky ([email protected]) * * These functions have standard call interface
@@ -22,17 +22,23 @@ 1: sacf 0 lr %r2,%r5 br %r14 -2: sll %r4,1 - srl %r4,1 - lhi %r3,-4096 - sll %r3,1 - srl %r3,1 - n %r3,__LC_TRANS_EXC_ADDR - sr %r3,%r4 - jm 1b - j 0b +2: lhi %r1,-4096 + lr %r3,%r4 + slr %r3,%r1 # %r3 = %r4 + 4096 + nr %r3,%r1 # %r3 = (%r4 + 4096) & -4096 + slr %r3,%r4 # %r3 = #bytes to next user page boundary + clr %r5,%r3 # copy crosses next page boundary ? + jnh 1b # no, this page fauled + # The page after the current user page might have faulted. + # We cant't find out which page because the program check handler + # might have callled schedule, destroying all lowcore information. + # We retry with the shortened length. +3: mvcle %r2,%r4,0 + jo 3b + j 1b .section __ex_table,"a" .long 0b,2b + .long 3b,1b .previous .align 4
@@ -46,17 +52,23 @@ 1: sacf 0 lr %r2,%r3 br %r14 -2: sll %r4,1 - srl %r4,1 - lhi %r5,-4096 - sll %r5,1 - srl %r5,1 - n %r5,__LC_TRANS_EXC_ADDR - sr %r5,%r4 - jm 1b - j 0b +2: lhi %r1,-4096 + lr %r5,%r4 + slr %r5,%r1 # %r5 = %r4 + 4096 + nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096 + slr %r5,%r4 # %r5 = #bytes to next user page boundary + clr %r3,%r5 # copy crosses next page boundary ? + jnh 1b # no, the current page fauled + # The page after the current user page might have faulted. + # We cant't find out which page because the program check handler + # might have callled schedule, destroying all lowcore information. + # We retry with the shortened length. +3: mvcle %r4,%r2,0 + jo 3b + j 1b .section __ex_table,"a" - .long 0b,2b + .long 0b,2b + .long 3b,1b .previous .align 4
@@ -71,18 +83,26 @@ 0: mvcle %r4,%r2,0 jo 0b 1: sacf 0 - lr %r2,%r3 br %r14 -2: sll %r4,1 - srl %r4,1 - lhi %r5,-4096 - sll %r5,1 - srl %r5,1 - n %r5,__LC_TRANS_EXC_ADDR - sr %r5,%r4 - jm 1b - j 0b +2: lr %r2,%r5 + lhi %r1,-4096 + slr %r5,%r1 # %r5 = %r4 + 4096 + nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096 + slr %r5,%r4 # %r5 = #bytes to next user page boundary + clr %r2,%r5 # copy crosses next page boundary ? + jnh 1b # no, the current page fauled + # The page after the current user page might have faulted. + # We cant't find out which page because the program check handler + # might have callled schedule, destroying all lowcore information. + # We retry with the shortened length. + slr %r2,%r5 +3: mvcle %r4,%r2,0 + jo 3b + j 1b +4: alr %r2,%r5 + j 1b .section __ex_table,"a" - .long 0b,2b + .long 0b,2b + .long 3b,4b .previous
arch/s390x/lib/uaccess.S +53 -24
104 lines not on this page · raw message
include/asm-s390/uaccess.h +9 -11
@@ -199,24 +199,23 @@*/ #define __put_user (x, ptr) \ ({ \ - __typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __x = (x); \ int __pu_err; \ switch (sizeof (*(ptr))) { \ case 1: \ __pu_err = __put_user_asm_1((__u8)(__u32) __x, \ - __pu_addr); \ + ptr); \ break; \ case 2: \ __pu_err = __put_user_asm_2((__u16)(__u32) __x, \ - __pu_addr); \ + ptr); \ break; \ case 4: \ __pu_err = __put_user_asm_4((__u32) __x, \ - __pu_addr); \ + ptr); \ break; \ case 8: \ - __pu_err = __put_user_asm_8(&__x, __pu_addr); \ + __pu_err = __put_user_asm_8(&__x, ptr); \ break; \ default: \ __pu_err = __put_user_bad(); \
@@ -333,21 +332,20 @@#define __get_user (x, ptr) \ ({ \ - __typeof__(ptr) __gu_addr = (ptr); \ __typeof__(*(ptr)) __x; \ int __gu_err; \ - switch (sizeof(*(__gu_addr))) { \ + switch (sizeof(*(ptr))) { \ case 1: \ - __get_user_asm_1(__x, __gu_addr, __gu_err); \ + __get_user_asm_1(__x, ptr, __gu_err); \ break; \ case 2: \ - __get_user_asm_2(__x, __gu_addr, __gu_err); \ + __get_user_asm_2(__x, ptr, __gu_err); \ break; \ case 4: \ - __get_user_asm_4(__x, __gu_addr, __gu_err); \ + __get_user_asm_4(__x, ptr, __gu_err); \ break; \ case 8: \ - __get_user_asm_8(__x, __gu_addr, __gu_err); \ + __get_user_asm_8(__x, ptr, __gu_err); \ break; \ default: \ __x = 0; \
include/asm-s390x/uaccess.h +9 -11
@@ -177,25 +177,24 @@*/ #define __put_user (x, ptr) \ ({ \ - __typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __x = (x); \ int __pu_err; \ - switch (sizeof (*(__pu_addr))) { \ + switch (sizeof (*(ptr))) { \ case 1: \ __pu_err = __put_user_asm_1((__u8)(__u64)(__x), \ - __pu_addr); \ + ptr); \ break; \ case 2: \ __pu_err = __put_user_asm_2((__u16)(__u64)(__x),\ - __pu_addr); \ + ptr); \ break; \ case 4: \ __pu_err = __put_user_asm_4((__u32)(__u64)(__x),\ - __pu_addr); \ + ptr); \ break; \ case 8: \ __pu_err = __put_user_asm_8((__u64)(__x), \ - __pu_addr); \ + ptr); \ break; \ default: \ __pu_err = __put_user_bad(); \
@@ -290,21 +289,20 @@#define __get_user (x, ptr) \ ({ \ - __typeof__(ptr) __gu_addr = (ptr); \ __typeof__(*(ptr)) __x; \ int __gu_err; \ switch (sizeof(*(ptr))) { \ case 1: \ - __get_user_asm_1(__x,__gu_addr,__gu_err); \ + __get_user_asm_1(__x,ptr,__gu_err); \ break; \ case 2: \ - __get_user_asm_2(__x,__gu_addr,__gu_err); \ + __get_user_asm_2(__x,ptr,__gu_err); \ break; \ case 4: \ - __get_user_asm_4(__x,__gu_addr,__gu_err); \ + __get_user_asm_4(__x,ptr,__gu_err); \ break; \ case 8: \ - __get_user_asm_8(__x,__gu_addr,__gu_err); \ + __get_user_asm_8(__x,ptr,__gu_err); \ break; \ default: \ __x = 0; \