kernel-hardening.lists.openwall.com archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: linux-arm-kernel@lists.infradead.org,
	kernel-hardening@lists.openwall.com, will.deacon@arm.com,
	catalin.marinas@arm.com, mark.rutland@arm.com,
	leif.lindholm@linaro.org, keescook@chromium.org,
	linux-kernel@vger.kernel.org
Cc: stuart.yoder@freescale.com, bhupesh.sharma@freescale.com,
	arnd@arndb.de, marc.zyngier@arm.com, christoffer.dall@linaro.org,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: [kernel-hardening] [PATCH v3 05/21] arm64: kvm: deal with kernel symbols outside of linear mapping
Date: Mon, 11 Jan 2016 14:18:58 +0100	[thread overview]
Message-ID: <1452518355-4606-6-git-send-email-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <1452518355-4606-1-git-send-email-ard.biesheuvel@linaro.org>

KVM on arm64 uses a fixed offset between the linear mapping at EL1 and
the HYP mapping at EL2. Before we can move the kernel virtual mapping
out of the linear mapping, we have to make sure that references to kernel
symbols that are accessed via the HYP mapping are translated to their
linear equivalent.

To prevent inadvertent direct references from sneaking in later, change
the type of all extern declarations to HYP kernel symbols to the opaque
'struct kvm_ksym', which does not decay to a pointer type like char arrays
and function references. This is not bullet proof, but at least forces the
user to take the address explicitly rather than referencing it directly.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm/include/asm/kvm_asm.h    |  2 ++
 arch/arm/include/asm/kvm_mmu.h    |  2 ++
 arch/arm/kvm/arm.c                |  5 +++--
 arch/arm/kvm/mmu.c                |  8 +++-----
 arch/arm64/include/asm/kvm_asm.h  | 19 ++++++++++++-------
 arch/arm64/include/asm/kvm_host.h |  8 +++++---
 arch/arm64/include/asm/kvm_mmu.h  |  2 ++
 arch/arm64/include/asm/virt.h     |  4 ----
 arch/arm64/kvm/debug.c            |  1 +
 arch/arm64/kvm/hyp.S              |  6 +++---
 10 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 194c91b610ff..484ffdf7c70b 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -99,6 +99,8 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
 extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+
+extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 405aa1883307..412b363f79e9 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -30,6 +30,8 @@
 #define HYP_PAGE_OFFSET		PAGE_OFFSET
 #define KERN_TO_HYP(kva)	(kva)
 
+#define kvm_ksym_ref(kva)	(kva)
+
 /*
  * Our virtual mapping for the boot-time MMU-enable code. Must be
  * shared across all the page-tables. Conveniently, we use the vectors
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index e06fd299de08..70e6d557c75f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -969,7 +969,7 @@ static void cpu_init_hyp_mode(void *dummy)
 	pgd_ptr = kvm_mmu_get_httbr();
 	stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
 	hyp_stack_ptr = stack_page + PAGE_SIZE;
-	vector_ptr = (unsigned long)__kvm_hyp_vector;
+	vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
 
 	__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
 
@@ -1061,7 +1061,8 @@ static int init_hyp_mode(void)
 	/*
 	 * Map the Hyp-code called directly from the host
 	 */
-	err = create_hyp_mappings(__kvm_hyp_code_start, __kvm_hyp_code_end);
+	err = create_hyp_mappings(kvm_ksym_ref(__kvm_hyp_code_start),
+				  kvm_ksym_ref(__kvm_hyp_code_end));
 	if (err) {
 		kvm_err("Cannot map world-switch code\n");
 		goto out_free_mappings;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 7dace909d5cf..9ab9e4b6376e 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -31,8 +31,6 @@
 
 #include "trace.h"
 
-extern char  __hyp_idmap_text_start[], __hyp_idmap_text_end[];
-
 static pgd_t *boot_hyp_pgd;
 static pgd_t *hyp_pgd;
 static pgd_t *merged_hyp_pgd;
@@ -1647,9 +1645,9 @@ int kvm_mmu_init(void)
 {
 	int err;
 
-	hyp_idmap_start = kvm_virt_to_phys(__hyp_idmap_text_start);
-	hyp_idmap_end = kvm_virt_to_phys(__hyp_idmap_text_end);
-	hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init);
+	hyp_idmap_start = kvm_virt_to_phys(&__hyp_idmap_text_start);
+	hyp_idmap_end = kvm_virt_to_phys(&__hyp_idmap_text_end);
+	hyp_idmap_vector = kvm_virt_to_phys(&__kvm_hyp_init);
 
 	/*
 	 * We rely on the linker script to ensure at build time that the HYP
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 5e377101f919..e3865845d3e1 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -105,24 +105,29 @@
 #ifndef __ASSEMBLY__
 struct kvm;
 struct kvm_vcpu;
+struct kvm_ksym;
 
 extern char __kvm_hyp_init[];
 extern char __kvm_hyp_init_end[];
 
-extern char __kvm_hyp_vector[];
+extern struct kvm_ksym __kvm_hyp_vector;
 
 #define	__kvm_hyp_code_start	__hyp_text_start
 #define	__kvm_hyp_code_end	__hyp_text_end
+extern struct kvm_ksym __hyp_text_start;
+extern struct kvm_ksym __hyp_text_end;
 
-extern void __kvm_flush_vm_context(void);
-extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
-extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
+extern struct kvm_ksym __kvm_flush_vm_context;
+extern struct kvm_ksym __kvm_tlb_flush_vmid_ipa;
+extern struct kvm_ksym __kvm_tlb_flush_vmid;
 
-extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
+extern struct kvm_ksym __kvm_vcpu_run;
 
-extern u64 __vgic_v3_get_ich_vtr_el2(void);
+extern struct kvm_ksym __hyp_idmap_text_start, __hyp_idmap_text_end;
 
-extern u32 __kvm_get_mdcr_el2(void);
+extern struct kvm_ksym __vgic_v3_get_ich_vtr_el2;
+
+extern struct kvm_ksym __kvm_get_mdcr_el2;
 
 #endif
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a35ce7266aac..90c6368ad7c8 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -222,7 +222,7 @@ static inline void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm,
 struct kvm_vcpu *kvm_arm_get_running_vcpu(void);
 struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void);
 
-u64 kvm_call_hyp(void *hypfn, ...);
+u64 __kvm_call_hyp(void *hypfn, ...);
 void force_vm_exit(const cpumask_t *mask);
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
 
@@ -243,8 +243,8 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
 	 * Call initialization code, and switch to the full blown
 	 * HYP code.
 	 */
-	kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
-		     hyp_stack_ptr, vector_ptr);
+	__kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
+		       hyp_stack_ptr, vector_ptr);
 }
 
 static inline void kvm_arch_hardware_disable(void) {}
@@ -258,4 +258,6 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
+#define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 61505676d085..0899026a2821 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -73,6 +73,8 @@
 
 #define KERN_TO_HYP(kva)	((unsigned long)kva - PAGE_OFFSET + HYP_PAGE_OFFSET)
 
+#define kvm_ksym_ref(sym)	((void *)&sym - KIMAGE_VADDR + PAGE_OFFSET)
+
 /*
  * We currently only support a 40bit IPA.
  */
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 7a5df5252dd7..215ad4649dd7 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -50,10 +50,6 @@ static inline bool is_hyp_mode_mismatched(void)
 	return __boot_cpu_mode[0] != __boot_cpu_mode[1];
 }
 
-/* The section containing the hypervisor text */
-extern char __hyp_text_start[];
-extern char __hyp_text_end[];
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* ! __ASM__VIRT_H */
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 47e5f0feaee8..f73d8c9b999b 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -24,6 +24,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_arm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_mmu.h>
 
 #include "trace.h"
 
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 86c289832272..309e3479dc2c 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -923,7 +923,7 @@ __hyp_panic_str:
 	.align	2
 
 /*
- * u64 kvm_call_hyp(void *hypfn, ...);
+ * u64 __kvm_call_hyp(void *hypfn, ...);
  *
  * This is not really a variadic function in the classic C-way and care must
  * be taken when calling this to ensure parameters are passed in registers
@@ -940,10 +940,10 @@ __hyp_panic_str:
  * used to implement __hyp_get_vectors in the same way as in
  * arch/arm64/kernel/hyp_stub.S.
  */
-ENTRY(kvm_call_hyp)
+ENTRY(__kvm_call_hyp)
 	hvc	#0
 	ret
-ENDPROC(kvm_call_hyp)
+ENDPROC(__kvm_call_hyp)
 
 .macro invalid_vector	label, target
 	.align	2
-- 
2.5.0

  parent reply	other threads:[~2016-01-11 13:18 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-11 13:18 [kernel-hardening] [PATCH v3 00/21] arm64: implement support for KASLR Ard Biesheuvel
2016-01-11 13:18 ` [kernel-hardening] [PATCH v3 01/21] of/fdt: make memblock minimum physical address arch configurable Ard Biesheuvel
2016-01-11 13:18 ` [kernel-hardening] [PATCH v3 02/21] arm64: introduce KIMAGE_VADDR as the virtual base of the kernel region Ard Biesheuvel
2016-01-11 16:31   ` [kernel-hardening] " Mark Rutland
2016-01-11 13:18 ` [kernel-hardening] [PATCH v3 03/21] arm64: pgtable: add dummy pud_index() and pmd_index() definitions Ard Biesheuvel
2016-01-11 17:40   ` [kernel-hardening] " Mark Rutland
2016-01-12 17:25     ` Ard Biesheuvel
2016-01-11 13:18 ` [kernel-hardening] [PATCH v3 04/21] arm64: decouple early fixmap init from linear mapping Ard Biesheuvel
2016-01-11 16:09   ` [kernel-hardening] " Mark Rutland
2016-01-11 16:15     ` Ard Biesheuvel
2016-01-11 16:27       ` Mark Rutland
2016-01-11 16:51         ` Mark Rutland
2016-01-11 17:08           ` Ard Biesheuvel
2016-01-11 17:15             ` Ard Biesheuvel
2016-01-11 17:21               ` Mark Rutland
2016-01-11 13:18 ` Ard Biesheuvel [this message]
2016-01-12 12:36   ` [kernel-hardening] Re: [PATCH v3 05/21] arm64: kvm: deal with kernel symbols outside of " Mark Rutland
2016-01-12 13:23     ` Ard Biesheuvel
2016-01-11 13:18 ` [kernel-hardening] [PATCH v3 06/21] arm64: pgtable: implement static [pte|pmd|pud]_offset variants Ard Biesheuvel
2016-01-11 16:24   ` [kernel-hardening] " Mark Rutland
2016-01-11 17:28     ` Ard Biesheuvel
2016-01-11 17:31       ` Mark Rutland
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 07/21] arm64: move kernel image to base of vmalloc area Ard Biesheuvel
2016-01-12 18:14   ` [kernel-hardening] " Mark Rutland
2016-01-13  8:39     ` Ard Biesheuvel
2016-01-13  9:58       ` Ard Biesheuvel
2016-01-13 11:11         ` Mark Rutland
2016-01-13 11:14           ` Ard Biesheuvel
2016-01-13 13:51       ` Mark Rutland
2016-01-13 15:50         ` Ard Biesheuvel
2016-01-13 16:26           ` Mark Rutland
2016-01-14 18:57         ` Mark Rutland
2016-01-15  9:54           ` Ard Biesheuvel
2016-01-15 11:23             ` Mark Rutland
2016-01-27 14:31               ` Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 08/21] arm64: add support for module PLTs Ard Biesheuvel
2016-01-22 16:55   ` [kernel-hardening] " Mark Rutland
2016-01-22 17:06     ` Ard Biesheuvel
2016-01-22 17:19       ` Mark Rutland
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 09/21] extable: add support for relative extables to search and sort routines Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 10/21] arm64: switch to relative exception tables Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 11/21] arm64: avoid R_AARCH64_ABS64 relocations for Image header fields Ard Biesheuvel
2016-01-13 18:12   ` [kernel-hardening] " Mark Rutland
2016-01-13 18:48     ` Ard Biesheuvel
2016-01-14  8:51       ` Ard Biesheuvel
2016-01-14  9:05         ` Ard Biesheuvel
2016-01-14 10:46           ` Mark Rutland
2016-01-14 11:22             ` Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 12/21] arm64: avoid dynamic relocations in early boot code Ard Biesheuvel
2016-01-14 17:09   ` [kernel-hardening] " Mark Rutland
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 13/21] arm64: allow kernel Image to be loaded anywhere in physical memory Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 14/21] arm64: redefine SWAPPER_TABLE_SHIFT for use in asm code Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 14/21] arm64: [re]define SWAPPER_TABLE_[SHIFT|SIZE] " Ard Biesheuvel
2016-01-11 13:26   ` [kernel-hardening] " Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 15/21] arm64: split elf relocs into a separate header Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 16/21] scripts/sortextable: add support for ET_DYN binaries Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 17/21] arm64: add support for a relocatable kernel and KASLR Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 18/21] efi: stub: implement efi_get_random_bytes() based on EFI_RNG_PROTOCOL Ard Biesheuvel
2016-01-21 15:42   ` [kernel-hardening] " Matt Fleming
2016-01-21 16:12     ` Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 19/21] efi: stub: add implementation of efi_random_alloc() Ard Biesheuvel
2016-01-21 16:10   ` [kernel-hardening] " Matt Fleming
2016-01-21 16:16     ` Ard Biesheuvel
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 20/21] efi: stub: use high allocation for converted command line Ard Biesheuvel
2016-01-21 16:20   ` [kernel-hardening] " Matt Fleming
2016-01-11 13:19 ` [kernel-hardening] [PATCH v3 21/21] arm64: efi: invoke EFI_RNG_PROTOCOL to supply KASLR randomness Ard Biesheuvel
2016-01-21 16:31   ` [kernel-hardening] " Matt Fleming
2016-01-11 22:07 ` [kernel-hardening] Re: [PATCH v3 00/21] arm64: implement support for KASLR Kees Cook
2016-01-12  7:17   ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1452518355-4606-6-git-send-email-ard.biesheuvel@linaro.org \
    --to=ard.biesheuvel@linaro.org \
    --cc=arnd@arndb.de \
    --cc=bhupesh.sharma@freescale.com \
    --cc=catalin.marinas@arm.com \
    --cc=christoffer.dall@linaro.org \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=leif.lindholm@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=stuart.yoder@freescale.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).