[PATCH v2 05/12] powerpc/dexcr: Support userspace ROP protection
Benjamin Gray
bgray at linux.ibm.com
Thu Mar 30 16:50:33 AEDT 2023
The ISA 3.1B hashst and hashchk instructions use a per-cpu SPR HASHKEYR
to hold a key used in the hash calculation. This key should be different
for each process to make it harder for a malicious process to recreate
valid hash values for a victim process.
Add support for storing a per-thread hash key, and setting/clearing
HASHKEYR appropriately.
Signed-off-by: Benjamin Gray <bgray at linux.ibm.com>
---
v1: * Guard HASHKEYR update behind change check
* HASHKEYR reset moved earlier to patch 2
---
arch/powerpc/include/asm/processor.h | 1 +
arch/powerpc/kernel/process.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index bad64d6a5d36..666d4e9804a8 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -264,6 +264,7 @@ struct thread_struct {
unsigned long mmcr3;
unsigned long sier2;
unsigned long sier3;
+ unsigned long hashkeyr;
#endif
};
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a7f9f3f85e20..a966adb5447f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1182,6 +1182,9 @@ static inline void save_sprs(struct thread_struct *t)
*/
t->tar = mfspr(SPRN_TAR);
}
+
+ if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
+ t->hashkeyr = mfspr(SPRN_HASHKEYR);
#endif
}
@@ -1260,6 +1263,10 @@ static inline void restore_sprs(struct thread_struct *old_thread,
if (cpu_has_feature(CPU_FTR_P9_TIDR) &&
old_thread->tidr != new_thread->tidr)
mtspr(SPRN_TIDR, new_thread->tidr);
+
+ if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) &&
+ old_thread->hashkeyr != new_thread->hashkeyr)
+ mtspr(SPRN_HASHKEYR, new_thread->hashkeyr);
#endif
}
@@ -1844,6 +1851,10 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs->ppr = DEFAULT_PPR;
p->thread.tidr = 0;
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
+ if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
+ p->thread.hashkeyr = current->thread.hashkeyr;
#endif
/*
* Run with the current AMR value of the kernel
@@ -1972,6 +1983,12 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
current->thread.tm_tfiar = 0;
current->thread.load_tm = 0;
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#ifdef CONFIG_PPC_BOOK3S_64
+ if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) {
+ current->thread.hashkeyr = get_random_long();
+ mtspr(SPRN_HASHKEYR, current->thread.hashkeyr);
+ }
+#endif /* CONFIG_PPC_BOOK3S_64 */
}
EXPORT_SYMBOL(start_thread);
--
2.39.2
More information about the Linuxppc-dev
mailing list