From: Greg Kroah-Hartman Date: Wed, 21 Nov 2012 01:36:54 +0000 (-0800) Subject: 3.6-stable patches X-Git-Tag: v3.0.53~23^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ce413b3374b8b6261c8de94a9d9a33a54532dc04;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: s390-signal-set-correct-address-space-control.patch --- diff --git a/queue-3.6/s390-signal-set-correct-address-space-control.patch b/queue-3.6/s390-signal-set-correct-address-space-control.patch new file mode 100644 index 00000000000..c767f4faebf --- /dev/null +++ b/queue-3.6/s390-signal-set-correct-address-space-control.patch @@ -0,0 +1,137 @@ +From fa968ee215c0ca91e4a9c3a69ac2405aae6e5d2f Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Wed, 7 Nov 2012 10:44:08 +0100 +Subject: s390/signal: set correct address space control + +From: Martin Schwidefsky + +commit fa968ee215c0ca91e4a9c3a69ac2405aae6e5d2f upstream. + +If user space is running in primary mode it can switch to secondary +or access register mode, this is used e.g. in the clock_gettime code +of the vdso. If a signal is delivered to the user space process while +it has been running in access register mode the signal handler is +executed in access register mode as well which will result in a crash +most of the time. + +Set the address space control bits in the PSW to the default for the +execution of the signal handler and make sure that the previous +address space control is restored on signal return. Take care +that user space can not switch to the kernel address space by +modifying the registers in the signal frame. + +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/include/asm/compat.h | 2 +- + arch/s390/include/asm/ptrace.h | 4 ++-- + arch/s390/kernel/compat_signal.c | 14 ++++++++++++-- + arch/s390/kernel/signal.c | 14 ++++++++++++-- + 4 files changed, 27 insertions(+), 7 deletions(-) + +--- a/arch/s390/include/asm/compat.h ++++ b/arch/s390/include/asm/compat.h +@@ -20,7 +20,7 @@ + #define PSW32_MASK_CC 0x00003000UL + #define PSW32_MASK_PM 0x00000f00UL + +-#define PSW32_MASK_USER 0x00003F00UL ++#define PSW32_MASK_USER 0x0000FF00UL + + #define PSW32_ADDR_AMODE 0x80000000UL + #define PSW32_ADDR_INSN 0x7FFFFFFFUL +--- a/arch/s390/include/asm/ptrace.h ++++ b/arch/s390/include/asm/ptrace.h +@@ -238,7 +238,7 @@ typedef struct + #define PSW_MASK_EA 0x00000000UL + #define PSW_MASK_BA 0x00000000UL + +-#define PSW_MASK_USER 0x00003F00UL ++#define PSW_MASK_USER 0x0000FF00UL + + #define PSW_ADDR_AMODE 0x80000000UL + #define PSW_ADDR_INSN 0x7FFFFFFFUL +@@ -267,7 +267,7 @@ typedef struct + #define PSW_MASK_EA 0x0000000100000000UL + #define PSW_MASK_BA 0x0000000080000000UL + +-#define PSW_MASK_USER 0x00003F0180000000UL ++#define PSW_MASK_USER 0x0000FF0180000000UL + + #define PSW_ADDR_AMODE 0x0000000000000000UL + #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL +--- a/arch/s390/kernel/compat_signal.c ++++ b/arch/s390/kernel/compat_signal.c +@@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_r + regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | + (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); ++ /* Check for invalid user address space control. */ ++ if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) ++ regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); + for (i = 0; i < NUM_GPRS; i++) + regs->gprs[i] = (__u64) regs32.gprs[i]; +@@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct + + /* Set up registers for signal handler */ + regs->gprs[15] = (__force __u64) frame; +- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ ++ /* Force 31 bit amode and default user address space control. */ ++ regs->psw.mask = PSW_MASK_BA | ++ (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.addr = (__force __u64) ka->sa.sa_handler; + + regs->gprs[2] = map_signal(sig); +@@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, str + + /* Set up registers for signal handler */ + regs->gprs[15] = (__force __u64) frame; +- regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ ++ /* Force 31 bit amode and default user address space control. */ ++ regs->psw.mask = PSW_MASK_BA | ++ (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.addr = (__u64) ka->sa.sa_handler; + + regs->gprs[2] = map_signal(sig); +--- a/arch/s390/kernel/signal.c ++++ b/arch/s390/kernel/signal.c +@@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_reg + /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ + regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | + (user_sregs.regs.psw.mask & PSW_MASK_USER); ++ /* Check for invalid user address space control. */ ++ if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) ++ regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + /* Check for invalid amode */ + if (regs->psw.mask & PSW_MASK_EA) + regs->psw.mask |= PSW_MASK_BA; +@@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k + + /* Set up registers for signal handler */ + regs->gprs[15] = (unsigned long) frame; +- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ ++ /* Force default amode and default user address space control. */ ++ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | ++ (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; + + regs->gprs[2] = map_signal(sig); +@@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struc + + /* Set up registers for signal handler */ + regs->gprs[15] = (unsigned long) frame; +- regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ ++ /* Force default amode and default user address space control. */ ++ regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | ++ (psw_user_bits & PSW_MASK_ASC) | ++ (regs->psw.mask & ~PSW_MASK_ASC); + regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; + + regs->gprs[2] = map_signal(sig); diff --git a/queue-3.6/series b/queue-3.6/series index 7ce7e13bee2..d3bd7feb83f 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -49,3 +49,4 @@ r8169-allow-multicast-packets-on-sub-8168f-chipset.patch netfilter-nf_nat-don-t-check-for-port-change-on-icmp-tuples.patch netfilter-xt_tee-don-t-use-destination-address-found-in-header.patch netfilter-nf_conntrack-fix-rt_gateway-checks-for-h.323-helper.patch +s390-signal-set-correct-address-space-control.patch