Skip to content

Commit cb86616

Browse files
author
Marc Zyngier
committed
Merge branch kvm-arm64/ubsan-el2 into kvmarm-master/next
* kvm-arm64/ubsan-el2: : . : Add UBSAN support to the EL2 portion of KVM, reusing most of the : existing logic provided by CONFIG_IBSAN_TRAP. : : Patches courtesy of Mostafa Saleh. : . KVM: arm64: Handle UBSAN faults KVM: arm64: Introduce CONFIG_UBSAN_KVM_EL2 ubsan: Remove regs from report_ubsan_failure() arm64: Introduce esr_is_ubsan_brk() Signed-off-by: Marc Zyngier <maz@kernel.org>
2 parents a90e001 + 4466927 commit cb86616

File tree

9 files changed

+41
-10
lines changed

9 files changed

+41
-10
lines changed

arch/arm64/include/asm/esr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,11 @@ static inline bool esr_is_cfi_brk(unsigned long esr)
440440
(esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE;
441441
}
442442

443+
static inline bool esr_is_ubsan_brk(unsigned long esr)
444+
{
445+
return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM;
446+
}
447+
443448
static inline bool esr_fsc_is_translation_fault(unsigned long esr)
444449
{
445450
esr = esr & ESR_ELx_FSC;

arch/arm64/kernel/traps.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ static struct break_hook kasan_break_hook = {
11181118
#ifdef CONFIG_UBSAN_TRAP
11191119
static int ubsan_handler(struct pt_regs *regs, unsigned long esr)
11201120
{
1121-
die(report_ubsan_failure(regs, esr & UBSAN_BRK_MASK), regs, esr);
1121+
die(report_ubsan_failure(esr & UBSAN_BRK_MASK), regs, esr);
11221122
return DBG_HOOK_HANDLED;
11231123
}
11241124

@@ -1145,7 +1145,7 @@ int __init early_brk64(unsigned long addr, unsigned long esr,
11451145
return kasan_handler(regs, esr) != DBG_HOOK_HANDLED;
11461146
#endif
11471147
#ifdef CONFIG_UBSAN_TRAP
1148-
if ((esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM)
1148+
if (esr_is_ubsan_brk(esr))
11491149
return ubsan_handler(regs, esr) != DBG_HOOK_HANDLED;
11501150
#endif
11511151
return bug_handler(regs, esr) != DBG_HOOK_HANDLED;

arch/arm64/kvm/handle_exit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/kvm.h>
1212
#include <linux/kvm_host.h>
13+
#include <linux/ubsan.h>
1314

1415
#include <asm/esr.h>
1516
#include <asm/exception.h>
@@ -474,6 +475,11 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
474475
print_nvhe_hyp_panic("BUG", panic_addr);
475476
} else if (IS_ENABLED(CONFIG_CFI_CLANG) && esr_is_cfi_brk(esr)) {
476477
kvm_nvhe_report_cfi_failure(panic_addr);
478+
} else if (IS_ENABLED(CONFIG_UBSAN_KVM_EL2) &&
479+
ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
480+
esr_is_ubsan_brk(esr)) {
481+
print_nvhe_hyp_panic(report_ubsan_failure(esr & UBSAN_BRK_MASK),
482+
panic_addr);
477483
} else {
478484
print_nvhe_hyp_panic("panic", panic_addr);
479485
}

arch/arm64/kvm/hyp/nvhe/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,9 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS), $(KBUILD_CFLAG
9999
# causes a build failure. Remove profile optimization flags.
100100
KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%, $(KBUILD_CFLAGS))
101101
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables
102+
103+
ifeq ($(CONFIG_UBSAN_KVM_EL2),y)
104+
UBSAN_SANITIZE := y
105+
# Always use brk and not hooks
106+
ccflags-y += $(CFLAGS_UBSAN_TRAP)
107+
endif

arch/x86/kernel/traps.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ static noinstr bool handle_bug(struct pt_regs *regs)
351351
case BUG_UD1_UBSAN:
352352
if (IS_ENABLED(CONFIG_UBSAN_TRAP)) {
353353
pr_crit("%s at %pS\n",
354-
report_ubsan_failure(regs, ud_imm),
354+
report_ubsan_failure(ud_imm),
355355
(void *)regs->ip);
356356
}
357357
break;

include/linux/ubsan.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
#ifndef _LINUX_UBSAN_H
33
#define _LINUX_UBSAN_H
44

5-
#ifdef CONFIG_UBSAN_TRAP
6-
const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type);
5+
#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2)
6+
const char *report_ubsan_failure(u32 check_type);
77
#else
8-
static inline const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
8+
static inline const char *report_ubsan_failure(u32 check_type)
99
{
1010
return NULL;
1111
}

lib/Kconfig.ubsan

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,13 @@ config TEST_UBSAN
165165
This is a test module for UBSAN.
166166
It triggers various undefined behavior, and detect it.
167167

168+
config UBSAN_KVM_EL2
169+
bool "UBSAN for KVM code at EL2"
170+
depends on ARM64
171+
help
172+
Enable UBSAN when running on ARM64 with KVM in a split mode
173+
(nvhe/hvhe/protected) for the hypervisor code running in EL2.
174+
In this mode, any UBSAN violation in EL2 would panic the kernel
175+
and information similar to UBSAN_TRAP would be printed.
176+
168177
endif # if UBSAN

lib/ubsan.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919

2020
#include "ubsan.h"
2121

22-
#ifdef CONFIG_UBSAN_TRAP
22+
#if defined(CONFIG_UBSAN_TRAP) || defined(CONFIG_UBSAN_KVM_EL2)
2323
/*
2424
* Only include matches for UBSAN checks that are actually compiled in.
2525
* The mappings of struct SanitizerKind (the -fsanitize=xxx args) to
2626
* enum SanitizerHandler (the traps) in Clang is in clang/lib/CodeGen/.
2727
*/
28-
const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
28+
const char *report_ubsan_failure(u32 check_type)
2929
{
3030
switch (check_type) {
3131
#ifdef CONFIG_UBSAN_BOUNDS
@@ -97,7 +97,9 @@ const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
9797
}
9898
}
9999

100-
#else
100+
#endif
101+
102+
#ifndef CONFIG_UBSAN_TRAP
101103
static const char * const type_check_kinds[] = {
102104
"load of",
103105
"store to",

scripts/Makefile.ubsan

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3+
# Shared with KVM/arm64.
4+
export CFLAGS_UBSAN_TRAP := $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error)
5+
36
# Enable available and selected UBSAN features.
47
ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT) += -fsanitize=alignment
58
ubsan-cflags-$(CONFIG_UBSAN_BOUNDS_STRICT) += -fsanitize=bounds-strict
@@ -10,7 +13,7 @@ ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO) += -fsanitize=integer-divide-by-zero
1013
ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE) += -fsanitize=unreachable
1114
ubsan-cflags-$(CONFIG_UBSAN_BOOL) += -fsanitize=bool
1215
ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum
13-
ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(call cc-option,-fsanitize-trap=undefined,-fsanitize-undefined-trap-on-error)
16+
ubsan-cflags-$(CONFIG_UBSAN_TRAP) += $(CFLAGS_UBSAN_TRAP)
1417

1518
export CFLAGS_UBSAN := $(ubsan-cflags-y)
1619

0 commit comments

Comments
 (0)