[PATCH] powerpc: Fix non-atomic stack pointer update in fortified longjmp (bug 34530)
Florian Weimer <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
After commit 78f1f0e39cd41d28ae771eb3498bc33780c85cfd ("Consolidate
the C pointer guard and align the assembly implementations"),
PTR_DEMANGLE3 on POWER no longer atomically updates the destination
register. The fortified longjmp relies on atomic update of the
stack pointer (r1) in sysdeps/powerpc/powerpc64/__longjmp-common.S
and parallel files:
#ifdef PTR_DEMANGLE
# ifdef CHECK_SP
PTR_DEMANGLE3 (r22, r22, r25)
# else
PTR_DEMANGLE3 (r1, r22, r25)
# endif
#endif
Fix this by using PTR_DEMANGLE2 instead of PTR_DEMANGLE3. Remove
PTR_MANGLE3 and PTR_DEMANGLE3 as unused.
An alternate fix would store the pointer guard cookie rotated,
but this would go against the unification in the commit that
introduced the regression.
---
sysdeps/powerpc/powerpc32/__longjmp-common.S | 10 ++++------
sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S | 11 ++++-------
sysdeps/powerpc/powerpc64/__longjmp-common.S | 16 ++++++----------
sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h | 8 --------
4 files changed, 14 insertions(+), 31 deletions(-)
diff --git a/sysdeps/powerpc/powerpc32/__longjmp-common.S b/sysdeps/powerpc/powerpc32/__longjmp-common.S
index eb228bf4fe..9da86330f7 100644
--- a/sysdeps/powerpc/powerpc32/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/__longjmp-common.S
@@ -30,11 +30,12 @@ ENTRY (__longjmp_symbol)
#if defined PTR_DEMANGLE || defined CHECK_SP
lwz r24,(JB_GPR1*4)(r3)
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r24, r25)
+# endif
# ifdef CHECK_SP
-# ifdef PTR_DEMANGLE
- PTR_DEMANGLE3 (r24, r24, r25)
-# endif
CHECK_SP (r24)
+# endif
mr r1,r24
# endif
#else
@@ -49,9 +50,6 @@ ENTRY (__longjmp_symbol)
lwz r19,((JB_GPRS+19-14)*4)(r3)
lwz r20,((JB_GPRS+20-14)*4)(r3)
#ifdef PTR_DEMANGLE
-# ifndef CHECK_SP
- PTR_DEMANGLE3 (r1, r24, r25)
-# endif
PTR_DEMANGLE2 (r0, r25)
#endif
/* longjmp/longjmp_target probe expects longjmp first argument (4@3),
diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
index c5acc1610c..8e383cc997 100644
--- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
@@ -114,13 +114,13 @@ L(no_vmx):
#endif
#if defined PTR_DEMANGLE || defined CHECK_SP
lwz r24,(JB_GPR1*4)(r3)
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r24, r25)
+# endif
# ifdef CHECK_SP
-# ifdef PTR_DEMANGLE
- PTR_DEMANGLE3 (r24, r24, r25)
-# endif
CHECK_SP (r24)
+# endif
mr r1,r24
-# endif
#else
lwz r1,(JB_GPR1*4)(r3)
#endif
@@ -140,9 +140,6 @@ L(no_vmx):
lwz r20,((JB_GPRS+6)*4)(r3)
lfd fp20,((JB_FPRS+6*2)*4)(r3)
#ifdef PTR_DEMANGLE
-# ifndef CHECK_SP
- PTR_DEMANGLE3 (r1, r24, r25)
-# endif
PTR_DEMANGLE2 (r0, r25)
#endif
/* longjmp/longjmp_target probe expects longjmp first argument (4@3),
diff --git a/sysdeps/powerpc/powerpc64/__longjmp-common.S b/sysdeps/powerpc/powerpc64/__longjmp-common.S
index 99b2718677..fe8488fcac 100644
--- a/sysdeps/powerpc/powerpc64/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc64/__longjmp-common.S
@@ -115,19 +115,15 @@ L(no_vmx):
#endif
#if defined PTR_DEMANGLE || defined CHECK_SP
ld r22,(JB_GPR1*8)(r3)
-#else
- ld r1,(JB_GPR1*8)(r3)
-#endif
-#ifdef PTR_DEMANGLE
+# ifdef PTR_DEMANGLE
+ PTR_DEMANGLE (r22, r25)
+# endif
# ifdef CHECK_SP
- PTR_DEMANGLE3 (r22, r22, r25)
-# else
- PTR_DEMANGLE3 (r1, r22, r25)
-# endif
-#endif
-#ifdef CHECK_SP
CHECK_SP (r22)
+# endif
mr r1,r22
+#else
+ ld r1,(JB_GPR1*8)(r3)
#endif
ld r2,(JB_GPR2*8)(r3)
ld r0,(JB_LR*8)(r3)
diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
index 962ad10e59..cb3e031467 100644
--- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
+++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard-asm.h
@@ -65,10 +65,6 @@
# define PTR_MANGLE2(reg, tmpreg) \
xor reg,tmpreg,reg; \
PTR_ROT_MANGLE (reg, reg)
-# define PTR_MANGLE3(destreg, reg, tmpreg) \
- PTR_GUARD_LOAD (tmpreg); \
- xor destreg,tmpreg,reg; \
- PTR_ROT_MANGLE (destreg, destreg)
# define PTR_DEMANGLE(reg, tmpreg) \
PTR_GUARD_LOAD (tmpreg); \
PTR_ROT_DEMANGLE (reg, reg); \
@@ -76,10 +72,6 @@
# define PTR_DEMANGLE2(reg, tmpreg) \
PTR_ROT_DEMANGLE (reg, reg); \
xor reg,tmpreg,reg
-# define PTR_DEMANGLE3(destreg, reg, tmpreg) \
- PTR_GUARD_LOAD (tmpreg); \
- PTR_ROT_DEMANGLE (destreg, reg); \
- xor destreg,tmpreg,destreg
#endif
#endif /* POINTER_GUARD_ASM_H */
base-commit: c6ddcef3985e887cf3a469549da2120c2b0e63fb