Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 642b2c37 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: protect kernel text from other bus masters"

parents 92339d10 97a47902
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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
@@ -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
+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
@@ -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

@@ -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");
@@ -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