@@ -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
};
@@ -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
new file mode 100644
@@ -0,0 +1,21 @@
+#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)
@@ -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
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> --- This differs from the previous iterations by making the reset value totally independent of the process's current DEXCR value. The original iterations stored an 'inherit' bitmask, where the mask decides which of the current DEXCR aspects are kept across exec, and the others are reset to a fixed default. That approach has a flaw when trying to prevent unauthorized inherited hash check disabling. With a hierarchy A -> B -> C of process execs, suppose A is privileged and enables NPHIE as an inherited aspect. If B is unprivileged but clears its NPHIE aspect, the clear is unintentionally inherited down to C as well (which may be setuid). This new approach lets processes control the reset value directly without any reference to the values the process itself is using. Compared to the original approach, we don't run into an issue where an unprivileged middle child ever controls the reset value. --- arch/powerpc/include/asm/processor.h | 2 +- arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/dexcr.c | 21 +++++++++++++++++++++ arch/powerpc/kernel/process.c | 7 +++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/kernel/dexcr.c