powerpc/dexcr: Reset DEXCR value across exec
authorBenjamin Gray <bgray@linux.ibm.com>
Wed, 17 Apr 2024 11:23:19 +0000 (21:23 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 3 May 2024 10:46:51 +0000 (20:46 +1000)
Inheriting the DEXCR across exec can have security and usability
concerns. If a program is compiled with hash instructions it generally
expects to run with NPHIE enabled. But if the parent process disables
NPHIE then if it's not careful it will be disabled for any children too
and the protection offered by hash checks is basically worthless.

This patch introduces a per-process reset value that new execs in a
particular process tree are initialized with. This enables fine grained
control over what DEXCR value child processes run with by default.
For example, containers running legacy binaries that expect hash
instructions to act as NOPs could configure the reset value of the
container root to control the default reset value for all members of
the container.

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
[mpe: Add missing SPDX tag on dexcr.c]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20240417112325.728010-4-bgray@linux.ibm.com
arch/powerpc/include/asm/processor.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/dexcr.c [new file with mode: 0644]
arch/powerpc/kernel/process.c

index 882e31296ea6baa16aa2fb891881e6ccc1bcdc73..aad85a24134ac3b1fd28084c31a14a98645f464d 100644 (file)
@@ -261,7 +261,7 @@ struct thread_struct {
        unsigned long   sier3;
        unsigned long   hashkeyr;
        unsigned long   dexcr;
-
+       unsigned long   dexcr_onexec;   /* Reset value to load on exec */
 #endif
 };
 
index d3282fbea4f2f5c3733068e950a050cb97d70bb9..1d183b077948b137f053f6dc44dc2056142ce844 100644 (file)
@@ -87,6 +87,7 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)      += hw_breakpoint.o
 obj-$(CONFIG_PPC_DAWR)         += dawr.o
 obj-$(CONFIG_PPC_BOOK3S_64)    += cpu_setup_ppc970.o cpu_setup_pa6t.o
 obj-$(CONFIG_PPC_BOOK3S_64)    += cpu_setup_power.o
+obj-$(CONFIG_PPC_BOOK3S_64)    += dexcr.o
 obj-$(CONFIG_PPC_BOOK3S_64)    += mce.o mce_power.o
 obj-$(CONFIG_PPC_BOOK3E_64)    += exceptions-64e.o idle_64e.o
 obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
diff --git a/arch/powerpc/kernel/dexcr.c b/arch/powerpc/kernel/dexcr.c
new file mode 100644 (file)
index 0000000..d5cd774
--- /dev/null
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/capability.h>
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/prctl.h>
+#include <linux/sched.h>
+
+#include <asm/cpu_has_feature.h>
+#include <asm/cputable.h>
+#include <asm/processor.h>
+#include <asm/reg.h>
+
+static int __init init_task_dexcr(void)
+{
+       if (!early_cpu_has_feature(CPU_FTR_ARCH_31))
+               return 0;
+
+       current->thread.dexcr_onexec = mfspr(SPRN_DEXCR);
+
+       return 0;
+}
+early_initcall(init_task_dexcr)
index d482c3fd81d7a506c91edd86accc474a950597cc..8ab779a3bddebed2be0d161f44849269a5c9e203 100644 (file)
@@ -1641,6 +1641,13 @@ void arch_setup_new_exec(void)
        current->thread.regs->amr  = default_amr;
        current->thread.regs->iamr  = default_iamr;
 #endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+       if (cpu_has_feature(CPU_FTR_ARCH_31)) {
+               current->thread.dexcr = current->thread.dexcr_onexec;
+               mtspr(SPRN_DEXCR, current->thread.dexcr);
+       }
+#endif /* CONFIG_PPC_BOOK3S_64 */
 }
 
 #ifdef CONFIG_PPC64