[PATCH v2] powerpc64le: _init/_fini file changes for ROP

Sachin Monga smonga@linux.ibm.com
Wed Oct 30 21:18:58 GMT 2024


The ROP instructions were added in ISA 3.1 (ie, Power10), however they
were defined so that if executed on older cpus, they would behave as
nops.  This allows us to emit them on older cpus and they'd just be
ignored, but if run on a Power10, then the binary would be ROP protected.

-mrop-protect is needed to compile glibc for ROP enablement.
However, power7 and earlier files should not use it.

Hash instructions use negative offsets so the default position
of ROP pointer is FRAME_ROP_SAVE from caller's SP.

Modified FRAME_MIN_SIZE_PARM to 112 for elfAbi2 to reserve
additional 16 bytes for ROP save slot and padding.

Signed-off-by: Sachin Monga <smonga@linux.ibm.com>
---
The patch was built on powerpc64le-linux and regression tested
with no errors.
 sysdeps/powerpc/powerpc64/crti.S             | 6 ++++++
 sysdeps/powerpc/powerpc64/crtn.S             | 6 ++++++
 sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 ++
 sysdeps/powerpc/powerpc64/sysdep.h           | 4 ++--
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/sysdeps/powerpc/powerpc64/crti.S b/sysdeps/powerpc/powerpc64/crti.S
index 71bdddfb3b..e977bc4b9c 100644
--- a/sysdeps/powerpc/powerpc64/crti.S
+++ b/sysdeps/powerpc/powerpc64/crti.S
@@ -68,6 +68,9 @@ BODY_LABEL (_init):
 	LOCALENTRY(_init)
 	mflr 0
 	std 0, FRAME_LR_SAVE(r1)
+#ifdef	__ROP_PROTECT__
+	hashst 0, FRAME_ROP_SAVE(r1)
+#endif
 	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
 #if PREINIT_FUNCTION_WEAK
 	addis r9, r2, .LC0@toc@ha
@@ -87,4 +90,7 @@ BODY_LABEL (_fini):
 	LOCALENTRY(_fini)
 	mflr 0
 	std 0, FRAME_LR_SAVE(r1)
+#ifdef	__ROP_PROTECT__
+	hashst 0, FRAME_ROP_SAVE(r1)
+#endif
 	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
diff --git a/sysdeps/powerpc/powerpc64/crtn.S b/sysdeps/powerpc/powerpc64/crtn.S
index 4e91231f2c..a37e159950 100644
--- a/sysdeps/powerpc/powerpc64/crtn.S
+++ b/sysdeps/powerpc/powerpc64/crtn.S
@@ -42,10 +42,16 @@
 	addi r1, r1, FRAME_MIN_SIZE_PARM
 	ld r0, FRAME_LR_SAVE(r1)
 	mtlr r0
+#ifdef	__ROP_PROTECT__
+	hashchk 0, FRAME_ROP_SAVE(r1)
+#endif
 	blr
 
 	.section .fini,"ax",@progbits
 	addi r1, r1, FRAME_MIN_SIZE_PARM
 	ld r0, FRAME_LR_SAVE(r1)
 	mtlr r0
+#ifdef	__ROP_PROTECT__
+	hashchk 0, FRAME_ROP_SAVE(r1)
+#endif
 	blr
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index b847c19049..840e517dad 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -38,7 +38,9 @@ sysdep_routines += memchr-power10 memcmp-power10 memcpy-power10 \
 		   strlen-power9 strncpy-power9 stpncpy-power9 strlen-power10
 endif
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
+CFLAGS-strncase-power7.c := $(filter-out -mrop-protect, $(CFLAGS-strncase-power7))
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
+CFLAGS-strncase_l-power7.c := $(filter-out -mrop-protect, $(CFLAGS-strncase-power7_l))
 endif
 
 # Called during static initialization
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index c439b06121..ba614172ed 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -24,15 +24,15 @@
 /* Stack frame offsets.  */
 #define FRAME_BACKCHAIN		0
 #define FRAME_CR_SAVE		8
+#define FRAME_ROP_SAVE		-8 /* Default ROP slot */
 #define FRAME_LR_SAVE		16
+#define FRAME_MIN_SIZE_PARM	112 /* ++ROP ++Padding for _CALL_ELF=2 */
 #if _CALL_ELF != 2
 #define FRAME_MIN_SIZE		112
-#define FRAME_MIN_SIZE_PARM	112
 #define FRAME_TOC_SAVE		40
 #define FRAME_PARM_SAVE		48
 #else
 #define FRAME_MIN_SIZE		32
-#define FRAME_MIN_SIZE_PARM	96
 #define FRAME_TOC_SAVE		24
 #define FRAME_PARM_SAVE		32
 #endif
-- 
2.47.0



More information about the Libc-alpha mailing list