From: Greg Kroah-Hartman Date: Thu, 27 Dec 2012 22:58:59 +0000 (-0800) Subject: 3.7-stable patches X-Git-Tag: v3.0.58~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=630af860e496f328977b68eafc054e51069e7cad;p=thirdparty%2Fkernel%2Fstable-queue.git 3.7-stable patches added patches: arm64-make-dirty-ptes-read-only.patch arm64-signal-push-the-unwinding-prologue-on-the-signal-stack.patch --- diff --git a/queue-3.7/arm64-make-dirty-ptes-read-only.patch b/queue-3.7/arm64-make-dirty-ptes-read-only.patch new file mode 100644 index 00000000000..c6334af5b4a --- /dev/null +++ b/queue-3.7/arm64-make-dirty-ptes-read-only.patch @@ -0,0 +1,31 @@ +From 33eaa58f854770dc9c98411a356c98e3a53edfda Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Wed, 28 Nov 2012 17:06:05 +0000 +Subject: arm64: Make !dirty ptes read-only + +From: Catalin Marinas + +commit 33eaa58f854770dc9c98411a356c98e3a53edfda upstream. + +The AArch64 Linux port relies on the mm code to wrprotect clean ptes. +This however is not the case with newly created ptes and +PAGE_SHARED(_EXEC) is writable but !dirty. + +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/pgtable.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -159,6 +159,8 @@ static inline void set_pte_at(struct mm_ + { + if (pte_present_exec_user(pte)) + __sync_icache_dcache(pte, addr); ++ if (!pte_dirty(pte)) ++ pte = pte_wrprotect(pte); + set_pte(ptep, pte); + } + diff --git a/queue-3.7/arm64-signal-push-the-unwinding-prologue-on-the-signal-stack.patch b/queue-3.7/arm64-signal-push-the-unwinding-prologue-on-the-signal-stack.patch new file mode 100644 index 00000000000..b472cd49b49 --- /dev/null +++ b/queue-3.7/arm64-signal-push-the-unwinding-prologue-on-the-signal-stack.patch @@ -0,0 +1,120 @@ +From 304ef4e8367244b547734143c792a2ab764831e8 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Fri, 23 Nov 2012 12:34:13 +0000 +Subject: arm64: signal: push the unwinding prologue on the signal stack + +From: Will Deacon + +commit 304ef4e8367244b547734143c792a2ab764831e8 upstream. + +To allow debuggers to unwind through signal frames, we create a fake +stack unwinding prologue containing the link register and frame pointer +of the interrupted context. The signal frame is then offset by 16 bytes +to make room for the two saved registers which are pushed onto the frame +of the *interrupted* context, rather than placed directly above the +signal stack. + +This doesn't work when an alternative signal stack is set up for a SEGV +handler, which is raised in response to RLIMIT_STACK being reached. In +this case, we try to push the unwinding prologue onto the full stack and +subsequently take a fault which we fail to resolve, causing setup_return +to return -EFAULT and handle_signal to force_sigsegv on the current task. + +This patch fixes the problem by including the unwinding prologue as part +of the rt_sigframe definition, which is populated during setup_sigframe, +ensuring that it always ends up on the signal stack. + +Signed-off-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/signal.c | 37 ++++++++++++++++--------------------- + 1 file changed, 16 insertions(+), 21 deletions(-) + +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -41,6 +41,8 @@ + struct rt_sigframe { + struct siginfo info; + struct ucontext uc; ++ u64 fp; ++ u64 lr; + }; + + static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) +@@ -175,6 +177,10 @@ static int setup_sigframe(struct rt_sigf + struct aux_context __user *aux = + (struct aux_context __user *)sf->uc.uc_mcontext.__reserved; + ++ /* set up the stack frame for unwinding */ ++ __put_user_error(regs->regs[29], &sf->fp, err); ++ __put_user_error(regs->regs[30], &sf->lr, err); ++ + for (i = 0; i < 31; i++) + __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + err); +@@ -210,9 +216,6 @@ static void __user *get_sigframe(struct + if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) + sp = sp_top = current->sas_ss_sp + current->sas_ss_size; + +- /* room for stack frame (FP, LR) */ +- sp -= 16; +- + sp = (sp - framesize) & ~15; + frame = (void __user *)sp; + +@@ -225,20 +228,14 @@ static void __user *get_sigframe(struct + return frame; + } + +-static int setup_return(struct pt_regs *regs, struct k_sigaction *ka, +- void __user *frame, int usig) ++static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, ++ void __user *frame, int usig) + { +- int err = 0; + __sigrestore_t sigtramp; +- unsigned long __user *sp = (unsigned long __user *)regs->sp; +- +- /* set up the stack frame */ +- __put_user_error(regs->regs[29], sp - 2, err); +- __put_user_error(regs->regs[30], sp - 1, err); + + regs->regs[0] = usig; +- regs->regs[29] = regs->sp - 16; + regs->sp = (unsigned long)frame; ++ regs->regs[29] = regs->sp + offsetof(struct rt_sigframe, fp); + regs->pc = (unsigned long)ka->sa.sa_handler; + + if (ka->sa.sa_flags & SA_RESTORER) +@@ -247,8 +244,6 @@ static int setup_return(struct pt_regs * + sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp); + + regs->regs[30] = (unsigned long)sigtramp; +- +- return err; + } + + static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, +@@ -272,13 +267,13 @@ static int setup_rt_frame(int usig, stru + err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); + + err |= setup_sigframe(frame, regs, set); +- if (err == 0) +- err = setup_return(regs, ka, frame, usig); +- +- if (err == 0 && ka->sa.sa_flags & SA_SIGINFO) { +- err |= copy_siginfo_to_user(&frame->info, info); +- regs->regs[1] = (unsigned long)&frame->info; +- regs->regs[2] = (unsigned long)&frame->uc; ++ if (err == 0) { ++ setup_return(regs, ka, frame, usig); ++ if (ka->sa.sa_flags & SA_SIGINFO) { ++ err |= copy_siginfo_to_user(&frame->info, info); ++ regs->regs[1] = (unsigned long)&frame->info; ++ regs->regs[2] = (unsigned long)&frame->uc; ++ } + } + + return err; diff --git a/queue-3.7/series b/queue-3.7/series index f9f86dd3ab1..dfc8af7f7be 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -6,3 +6,5 @@ b43-fix-tx-path-skb-leaks.patch pnpacpi-fix-incorrect-test_alpha-test.patch sgi-xp-handle-non-fatal-traps.patch exec-do-not-leave-bprm-interp-on-stack.patch +arm64-make-dirty-ptes-read-only.patch +arm64-signal-push-the-unwinding-prologue-on-the-signal-stack.patch