diff --git a/aarch64-setcontext.patch b/aarch64-setcontext.patch new file mode 100644 index 0000000..9997ff5 --- /dev/null +++ b/aarch64-setcontext.patch @@ -0,0 +1,225 @@ +From 4dc40de1ed58a1de5d960e59f20a04191f6820c9 Mon Sep 17 00:00:00 2001 +From: Will Newton +Date: Wed, 12 Mar 2014 16:14:51 +0000 +Subject: [PATCH 1/3] aarch64: Re-implement setcontext without rt_sigreturn + syscall + +The current implementation of setcontext uses rt_sigreturn to restore +the contents of registers. This contrasts with the way most other +architectures implement setcontext: + + powerpc64, mips, tile: + + Call rt_sigreturn if context was created by a call to a signal handler, + otherwise restore in user code. + + powerpc32: + + Call swapcontext system call and don't call sigreturn or rt_sigreturn. + + x86_64, sparc, hppa, sh, ia64, m68k, s390, arm: + + Only support restoring "synchronous" contexts, that is contexts + created by getcontext, and restoring in user code and don't call + sigreturn or rt_sigreturn. + + alpha: + + Call sigreturn (but not rt_sigreturn) in all cases to do the restore. + +The text of the setcontext manpage suggests that the requirement to be +able to restore a signal handler created context has been dropped from +SUSv2: + + If the context was obtained by a call to a signal handler, then old + standard text says that "program execution continues with the program + instruction following the instruction interrupted by the signal". + However, this sentence was removed in SUSv2, and the present verdict + is "the result is unspecified". + +Implementing setcontext by calling rt_sigreturn unconditionally causes +problems when used with sigaltstack as in BZ #16629. On this basis it +seems that aarch64 is broken and that new ports should only support +restoring contexts created with getcontext and do not need to call +rt_sigreturn at all. + +This patch re-implements the aarch64 setcontext function to restore +the context in user code in a similar manner to x86_64 and other ports. + +ChangeLog: + +2014-03-13 Will Newton + + [BZ #16629] + * sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext): + Re-implement to restore registers in user code and avoid + rt_sigreturn system call. +--- + sysdeps/unix/sysv/linux/aarch64/setcontext.S | 147 +++++++++++++++++---------- + 1 file changed, 92 insertions(+), 55 deletions(-) + +Index: glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +=================================================================== +--- glibc-2.19.orig/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S ++++ glibc-2.19/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +@@ -22,68 +22,105 @@ + #include "ucontext_i.h" + #include "ucontext-internal.h" + +-/* int setcontext (const ucontext_t *ucp) */ ++/* int __setcontext (const ucontext_t *ucp) + +- .text +- +-ENTRY(__setcontext) ++ Restores the machine context in UCP and thereby resumes execution ++ in that context. + +- /* Create a signal frame on the stack: ++ This implementation is intended to be used for *synchronous* context ++ switches only. Therefore, it does not have to restore anything ++ other than the PRESERVED state. */ + +- fp +- lr +- ... +- sp-> rt_sigframe +- */ +- +- stp x29, x30, [sp, -16]! +- cfi_adjust_cfa_offset (16) +- cfi_rel_offset (x29, 0) +- cfi_rel_offset (x30, 8) +- +- mov x29, sp +- cfi_def_cfa_register (x29) +- +- /* Allocate space for the sigcontext. */ +- mov w3, #((RT_SIGFRAME_SIZE + SP_ALIGN_SIZE) & SP_ALIGN_MASK) +- sub sp, sp, x3 +- +- /* Compute the base address of the ucontext structure. */ +- add x1, sp, #RT_SIGFRAME_UCONTEXT +- +- /* Only ucontext is required in the frame, *copy* it in. */ +- +-#if UCONTEXT_SIZE % 16 +-#error The implementation of setcontext.S assumes sizeof(ucontext_t) % 16 == 0 +-#endif +- +- mov x2, #UCONTEXT_SIZE / 16 +-0: +- ldp x3, x4, [x0], #16 +- stp x3, x4, [x1], #16 +- sub x2, x2, 1 +- cbnz x2, 0b ++ .text + +- /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe. */ +- mov x8, SYS_ify (rt_sigreturn) ++ENTRY (__setcontext) ++ /* Save a copy of UCP. */ ++ mov x9, x0 ++ ++ /* Set the signal mask with ++ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */ ++ mov x0, #SIG_SETMASK ++ add x1, x9, #UCONTEXT_SIGMASK ++ mov x2, #0 ++ mov x3, #_NSIG8 ++ mov x8, SYS_ify (rt_sigprocmask) + svc 0 +- +- /* Ooops we failed. Recover the stack */ +- +- mov sp, x29 +- cfi_def_cfa_register (sp) +- +- ldp x29, x30, [sp], 16 +- cfi_adjust_cfa_offset (16) +- cfi_restore (x29) +- cfi_restore (x30) +- b C_SYMBOL_NAME(__syscall_error) +- ++ cbz x0, 1f ++ b C_SYMBOL_NAME (__syscall_error) ++1: ++ /* Restore the general purpose registers. */ ++ mov x0, x9 ++ cfi_def_cfa (x0, 0) ++ cfi_offset (x18, oX0 + 18 * SZREG) ++ cfi_offset (x19, oX0 + 19 * SZREG) ++ cfi_offset (x20, oX0 + 20 * SZREG) ++ cfi_offset (x21, oX0 + 21 * SZREG) ++ cfi_offset (x22, oX0 + 22 * SZREG) ++ cfi_offset (x23, oX0 + 23 * SZREG) ++ cfi_offset (x24, oX0 + 24 * SZREG) ++ cfi_offset (x25, oX0 + 25 * SZREG) ++ cfi_offset (x26, oX0 + 26 * SZREG) ++ cfi_offset (x27, oX0 + 27 * SZREG) ++ cfi_offset (x28, oX0 + 28 * SZREG) ++ cfi_offset (x29, oX0 + 29 * SZREG) ++ cfi_offset (x30, oX0 + 30 * SZREG) ++ ++ cfi_offset ( d8, oV0 + 8 * SZVREG) ++ cfi_offset ( d9, oV0 + 9 * SZVREG) ++ cfi_offset (d10, oV0 + 10 * SZVREG) ++ cfi_offset (d11, oV0 + 11 * SZVREG) ++ cfi_offset (d12, oV0 + 12 * SZVREG) ++ cfi_offset (d13, oV0 + 13 * SZVREG) ++ cfi_offset (d14, oV0 + 14 * SZVREG) ++ cfi_offset (d15, oV0 + 15 * SZVREG) ++ ldp x18, x19, [x0, oX0 + 18 * SZREG] ++ ldp x20, x21, [x0, oX0 + 20 * SZREG] ++ ldp x22, x23, [x0, oX0 + 22 * SZREG] ++ ldp x24, x25, [x0, oX0 + 24 * SZREG] ++ ldp x26, x27, [x0, oX0 + 26 * SZREG] ++ ldp x28, x29, [x0, oX0 + 28 * SZREG] ++ ldr x30, [x0, oX0 + 30 * SZREG] ++ ldr x2, [x0, oSP] ++ mov sp, x2 ++ ++ /* Check for FP SIMD context. */ ++ add x2, x0, #oEXTENSION ++ ++ mov w3, #(FPSIMD_MAGIC & 0xffff) ++ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 ++ ldr w1, [x2, #oHEAD + oMAGIC] ++ cmp w1, w3 ++ b.ne 2f ++ ++ /* Restore the FP SIMD context. */ ++ add x3, x2, #oV0 + 8 * SZVREG ++ ldp d8, d9, [x3], #2 * SZVREG ++ ldp d10, d11, [x3], #2 * SZVREG ++ ldp d12, d13, [x3], #2 * SZVREG ++ ldp d14, d15, [x3], #2 * SZVREG ++ ++ add x3, x2, oFPSR ++ ++ ldr w4, [x3] ++ msr fpsr, x4 ++ ++ ldr w4, [x3, oFPCR - oFPSR] ++ msr fpcr, x4 ++ ++2: ++ ldr x16, [x0, oPC] ++ /* Restore arg registers. */ ++ ldp x2, x3, [x0, oX0 + 2 * SZREG] ++ ldp x4, x5, [x0, oX0 + 4 * SZREG] ++ ldp x6, x7, [x0, oX0 + 6 * SZREG] ++ ldp x0, x1, [x0, oX0 + 0 * SZREG] ++ /* Jump to the new pc value. */ ++ br x16 + PSEUDO_END (__setcontext) + weak_alias (__setcontext, setcontext) + +-ENTRY(__startcontext) ++ENTRY (__startcontext) + mov x0, x19 + cbnz x0, __setcontext +-1: b HIDDEN_JUMPTARGET(_exit) +-END(__startcontext) ++1: b HIDDEN_JUMPTARGET (_exit) ++END (__startcontext) diff --git a/glibc-testsuite.changes b/glibc-testsuite.changes index 8ce95dc..621a553 100644 --- a/glibc-testsuite.changes +++ b/glibc-testsuite.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Apr 1 07:55:19 UTC 2014 - schwab@suse.de + +- ppc64-copysign.patch: Fix ppc64le copysign overwriting parent stack + frame (BZ #16786) +- aarch64-setcontext.patch: Fix aarch64 setcontext clobbering alternate + signal stack (BZ #16629) + ------------------------------------------------------------------- Mon Mar 31 13:22:56 UTC 2014 - schwab@suse.de diff --git a/glibc-testsuite.spec b/glibc-testsuite.spec index e4bdad0..8c00dbb 100644 --- a/glibc-testsuite.spec +++ b/glibc-testsuite.spec @@ -244,6 +244,8 @@ Patch1004: powerpc-opt-power8.patch Patch1005: check-pf-alloca.patch # PATCH-FIX-UPSTREAM Fix use of half-initialized result in getaddrinfo when using nscd Patch1006: getaddrinfo-uninit-result.patch +# PATCH-FIX-UPSTREAM Fix ppc64le copysign overwriting parent stack frame (BZ #16786) +Patch1007: ppc64-copysign.patch ### # Patches awaiting upstream approval @@ -258,6 +260,8 @@ Patch2002: ldd-system-interp.patch Patch2003: abort-no-flush.patch # PATCH-FIX-UPSTREAM Skip checks in pthread_mutex_destroy when doing elision Patch2004: pthread-mutex-destroy.patch +# PATCH-FIX-UPSTREAM Fix aarch64 setcontext clobbering alternate signal stack (BZ #16629) +Patch2005: aarch64-setcontext.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -465,12 +469,14 @@ rm nscd/s-stamp %patch1004 -p1 %patch1005 -p1 %patch1006 -p1 +%patch1007 -p1 %patch2000 -p1 %patch2001 -p1 %patch2002 -p1 %patch2003 -p1 %patch2004 -p1 +%patch2005 -p1 %patch3000 diff --git a/glibc-utils.changes b/glibc-utils.changes index 8ce95dc..621a553 100644 --- a/glibc-utils.changes +++ b/glibc-utils.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Apr 1 07:55:19 UTC 2014 - schwab@suse.de + +- ppc64-copysign.patch: Fix ppc64le copysign overwriting parent stack + frame (BZ #16786) +- aarch64-setcontext.patch: Fix aarch64 setcontext clobbering alternate + signal stack (BZ #16629) + ------------------------------------------------------------------- Mon Mar 31 13:22:56 UTC 2014 - schwab@suse.de diff --git a/glibc-utils.spec b/glibc-utils.spec index ef4f6d7..012da23 100644 --- a/glibc-utils.spec +++ b/glibc-utils.spec @@ -243,6 +243,8 @@ Patch1004: powerpc-opt-power8.patch Patch1005: check-pf-alloca.patch # PATCH-FIX-UPSTREAM Fix use of half-initialized result in getaddrinfo when using nscd Patch1006: getaddrinfo-uninit-result.patch +# PATCH-FIX-UPSTREAM Fix ppc64le copysign overwriting parent stack frame (BZ #16786) +Patch1007: ppc64-copysign.patch ### # Patches awaiting upstream approval @@ -257,6 +259,8 @@ Patch2002: ldd-system-interp.patch Patch2003: abort-no-flush.patch # PATCH-FIX-UPSTREAM Skip checks in pthread_mutex_destroy when doing elision Patch2004: pthread-mutex-destroy.patch +# PATCH-FIX-UPSTREAM Fix aarch64 setcontext clobbering alternate signal stack (BZ #16629) +Patch2005: aarch64-setcontext.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -465,12 +469,14 @@ rm nscd/s-stamp %patch1004 -p1 %patch1005 -p1 %patch1006 -p1 +%patch1007 -p1 %patch2000 -p1 %patch2001 -p1 %patch2002 -p1 %patch2003 -p1 %patch2004 -p1 +%patch2005 -p1 %patch3000 diff --git a/glibc.changes b/glibc.changes index 8ce95dc..621a553 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Apr 1 07:55:19 UTC 2014 - schwab@suse.de + +- ppc64-copysign.patch: Fix ppc64le copysign overwriting parent stack + frame (BZ #16786) +- aarch64-setcontext.patch: Fix aarch64 setcontext clobbering alternate + signal stack (BZ #16629) + ------------------------------------------------------------------- Mon Mar 31 13:22:56 UTC 2014 - schwab@suse.de diff --git a/glibc.spec b/glibc.spec index 2359870..d74e8d3 100644 --- a/glibc.spec +++ b/glibc.spec @@ -244,6 +244,8 @@ Patch1004: powerpc-opt-power8.patch Patch1005: check-pf-alloca.patch # PATCH-FIX-UPSTREAM Fix use of half-initialized result in getaddrinfo when using nscd Patch1006: getaddrinfo-uninit-result.patch +# PATCH-FIX-UPSTREAM Fix ppc64le copysign overwriting parent stack frame (BZ #16786) +Patch1007: ppc64-copysign.patch ### # Patches awaiting upstream approval @@ -258,6 +260,8 @@ Patch2002: ldd-system-interp.patch Patch2003: abort-no-flush.patch # PATCH-FIX-UPSTREAM Skip checks in pthread_mutex_destroy when doing elision Patch2004: pthread-mutex-destroy.patch +# PATCH-FIX-UPSTREAM Fix aarch64 setcontext clobbering alternate signal stack (BZ #16629) +Patch2005: aarch64-setcontext.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -465,12 +469,14 @@ rm nscd/s-stamp %patch1004 -p1 %patch1005 -p1 %patch1006 -p1 +%patch1007 -p1 %patch2000 -p1 %patch2001 -p1 %patch2002 -p1 %patch2003 -p1 %patch2004 -p1 +%patch2005 -p1 %patch3000 diff --git a/ppc64-copysign.patch b/ppc64-copysign.patch new file mode 100644 index 0000000..5cdcb94 --- /dev/null +++ b/ppc64-copysign.patch @@ -0,0 +1,23 @@ +2014-04-01 Alan Modra + + [BZ #16786] + * sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack. + +Index: glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +=================================================================== +--- glibc-2.19.orig/sysdeps/powerpc/powerpc64/fpu/s_copysign.S ++++ glibc-2.19/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +@@ -27,11 +27,11 @@ ENTRY(__copysign) + /* double [f1] copysign (double [f1] x, double [f2] y); + copysign(x,y) returns a value with the magnitude of x and + with the sign bit of y. */ +- stfd fp2,56(r1) ++ stfd fp2,-8(r1) + nop + nop + nop +- ld r3,56(r1) ++ ld r3,-8(r1) + cmpdi r3,0 + blt L(0) + fabs fp1,fp1