[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.