[glibc] powerpc: Fix non-atomic stack pointer update in fortified longjmp (bug 34530)

Florian Weimer via Glibc-cvs <[email protected]>
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=24d188a2a149b9933e17240e454f917e065cdf06

commit 24d188a2a149b9933e17240e454f917e065cdf06
Author: Florian Weimer <[email protected]>
Date:   Tue Aug 18 21:48:34 2026 +0200

    powerpc: Fix non-atomic stack pointer update in fortified longjmp (bug 34530)
    
    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_DEMANGLE 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.
    
    Reviewed-by: Adhemerval Zanella  <[email protected]>

Diff:
---
 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)
-	mr r1,r24
 # endif
+	mr r1,r24
 #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 CHECK_SP
-	PTR_DEMANGLE3 (r22, r22, r25)
-# else
-	PTR_DEMANGLE3 (r1, r22, r25)
+# ifdef PTR_DEMANGLE
+	PTR_DEMANGLE (r22, r25)
 # endif
-#endif
-#ifdef CHECK_SP
+# 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 */
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.