Loading drivers/soc/qcom/Kconfig +13 −1 Original line number Diff line number Diff line Loading @@ -782,7 +782,7 @@ config MSM_PACMAN peripheral (BLSP) ownership. config MSM_KERNEL_PROTECT bool "Protect kernel text by removing write permissions in stage-2" bool "Protect kernel text by removing write permissions" depends on !FUNCTION_TRACER help On hypervisor-enabled targets, this option will make a call into Loading @@ -795,6 +795,18 @@ config MSM_KERNEL_PROTECT aarch64_insn_patch_text_nosync, etc. including the various CPU errata workarounds in arch/arm64/kernel/cpu_errata.c). For MPU based protection-enabled targets please refer to MSM_KERNEL_PROTECT_MPU config MSM_KERNEL_PROTECT_MPU bool "Protect kernel text from other masters by MPU" depends on MSM_KERNEL_PROTECT help On MPU based protection enabled targets, this option will make a call into TrustZone to request that the kernel text be ptotected for any write access from external bus masters. This protects against malicious devices rewriting kernel code. config MSM_KERNEL_PROTECT_TEST bool "Bootup test of kernel protection (INTENTIONAL CRASH)" depends on MSM_KERNEL_PROTECT Loading drivers/soc/qcom/kernel_protect.c +34 −4 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,10 +14,12 @@ #include <linux/printk.h> #include <linux/init.h> #include <linux/gfp.h> #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #include <asm/sections.h> #include <asm/cacheflush.h> #define KERNEL_PROTECT_MPU 0x24 #ifdef CONFIG_MSM_KERNEL_PROTECT_TEST Loading @@ -38,6 +40,10 @@ static void msm_protect_kernel_test(void) */ char *addr = (char *)__alloc_pages_nodemask; if (IS_ENABLED(CONFIG_MSM_KERNEL_PROTECT_MPU)) { pr_err("MPU protected kernel code is HLOS writable\n"); return; } pr_err("Checking whether the kernel text is writable...\n"); pr_err("A BUG means it is writable (this is bad)\n"); pr_err("A stage-2 fault means it's not writable (this is good, but we'll still crash)\n"); Loading Loading @@ -84,9 +90,33 @@ static int __init msm_protect_kernel(void) pr_debug("assigning from phys: %pa to %pa\n", &kernel_x_start_rounded, &kernel_x_end); pr_debug("virtual: %p to %p\n", virt_start, virt_end); if (IS_ENABLED(CONFIG_MSM_KERNEL_PROTECT_MPU)) { struct scm_desc desc = {0}; if (!scm_is_call_available(SCM_SVC_MP, KERNEL_PROTECT_MPU)) return 0; desc.args[0] = kernel_x_start_rounded; desc.args[1] = kernel_x_end - kernel_x_start_rounded; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, KERNEL_PROTECT_MPU), &desc); if (ret) { /* * must not proceed if failed to MPU protect kernel * text region */ panic("Failed to protect kernel region %pa -- %pa\n", &kernel_x_start_rounded, &kernel_x_end); } } else { ret = hyp_assign_phys(kernel_x_start_rounded, kernel_x_end - kernel_x_start_rounded, &vmid_hlos, 1, &vmid_hlos, &dest_perms, 1); } if (ret) /* * We want to fail relatively silently since not all Loading Loading
drivers/soc/qcom/Kconfig +13 −1 Original line number Diff line number Diff line Loading @@ -782,7 +782,7 @@ config MSM_PACMAN peripheral (BLSP) ownership. config MSM_KERNEL_PROTECT bool "Protect kernel text by removing write permissions in stage-2" bool "Protect kernel text by removing write permissions" depends on !FUNCTION_TRACER help On hypervisor-enabled targets, this option will make a call into Loading @@ -795,6 +795,18 @@ config MSM_KERNEL_PROTECT aarch64_insn_patch_text_nosync, etc. including the various CPU errata workarounds in arch/arm64/kernel/cpu_errata.c). For MPU based protection-enabled targets please refer to MSM_KERNEL_PROTECT_MPU config MSM_KERNEL_PROTECT_MPU bool "Protect kernel text from other masters by MPU" depends on MSM_KERNEL_PROTECT help On MPU based protection enabled targets, this option will make a call into TrustZone to request that the kernel text be ptotected for any write access from external bus masters. This protects against malicious devices rewriting kernel code. config MSM_KERNEL_PROTECT_TEST bool "Bootup test of kernel protection (INTENTIONAL CRASH)" depends on MSM_KERNEL_PROTECT Loading
drivers/soc/qcom/kernel_protect.c +34 −4 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -14,10 +14,12 @@ #include <linux/printk.h> #include <linux/init.h> #include <linux/gfp.h> #include <soc/qcom/scm.h> #include <soc/qcom/secure_buffer.h> #include <asm/sections.h> #include <asm/cacheflush.h> #define KERNEL_PROTECT_MPU 0x24 #ifdef CONFIG_MSM_KERNEL_PROTECT_TEST Loading @@ -38,6 +40,10 @@ static void msm_protect_kernel_test(void) */ char *addr = (char *)__alloc_pages_nodemask; if (IS_ENABLED(CONFIG_MSM_KERNEL_PROTECT_MPU)) { pr_err("MPU protected kernel code is HLOS writable\n"); return; } pr_err("Checking whether the kernel text is writable...\n"); pr_err("A BUG means it is writable (this is bad)\n"); pr_err("A stage-2 fault means it's not writable (this is good, but we'll still crash)\n"); Loading Loading @@ -84,9 +90,33 @@ static int __init msm_protect_kernel(void) pr_debug("assigning from phys: %pa to %pa\n", &kernel_x_start_rounded, &kernel_x_end); pr_debug("virtual: %p to %p\n", virt_start, virt_end); if (IS_ENABLED(CONFIG_MSM_KERNEL_PROTECT_MPU)) { struct scm_desc desc = {0}; if (!scm_is_call_available(SCM_SVC_MP, KERNEL_PROTECT_MPU)) return 0; desc.args[0] = kernel_x_start_rounded; desc.args[1] = kernel_x_end - kernel_x_start_rounded; desc.arginfo = SCM_ARGS(2); ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, KERNEL_PROTECT_MPU), &desc); if (ret) { /* * must not proceed if failed to MPU protect kernel * text region */ panic("Failed to protect kernel region %pa -- %pa\n", &kernel_x_start_rounded, &kernel_x_end); } } else { ret = hyp_assign_phys(kernel_x_start_rounded, kernel_x_end - kernel_x_start_rounded, &vmid_hlos, 1, &vmid_hlos, &dest_perms, 1); } if (ret) /* * We want to fail relatively silently since not all Loading