2021-01-14 17:26:25

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 0/9] UBSan Enablement for hyp/nVHE code

Respin of George's patch series enabling UBSAN for hyp/nVHE code.

Modification in v2:
* CONFIG_KVM_ARM_DEBUG_BUFFER removed; __kvm_check_ubsan_buffer is
called directly instead of via __kvm_arm_check_debug_buffer.
* Bugfixing commits removed as these are already upstream.
* Some code brought up to date, i.e. moved from entry.S to host.S.
* Merged "Add support for creating and checking a buffer" and
"Add a buffer that can pass UBSan data from hyp/nVHE" into
one commit as these changes don't work without each other.

George Popescu (9):
KVM: arm64: Enable UBSan instrumentation in nVHE hyp code
KVM: arm64: Add a buffer that can pass UBSan data from hyp/nVHE to
kernel
KVM: arm64: Enable UBSAN_BOUNDS for the both the kernel and hyp/nVHE
KVM: arm64: Enable UBsan check for unreachable code inside hyp/nVHE
code
KVM: arm64: Enable shift out of bounds undefined behaviour check for
hyp/nVHE
KVM: arm64: __ubsan_handle_load_invalid_value EL2 implementation.
KVM: arm64: Detect type mismatch undefined behaviour from hyp/nVHE
code
KVM: arm64: Detect arithmetic overflow is inside hyp/nVHE.
KVM: arm64: Add UBSan tests for PKVM.

arch/arm64/include/asm/assembler.h | 10 ++
arch/arm64/include/asm/kvm_debug_buffer.h | 34 ++++
arch/arm64/include/asm/kvm_host.h | 8 +-
arch/arm64/include/asm/kvm_ubsan.h | 50 ++++++
arch/arm64/kvm/Makefile | 2 +
arch/arm64/kvm/arm.c | 9 ++
arch/arm64/kvm/hyp/include/hyp/test_ubsan.h | 112 +++++++++++++
arch/arm64/kvm/hyp/nvhe/Makefile | 3 +-
arch/arm64/kvm/hyp/nvhe/host.S | 4 +
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 3 +
arch/arm64/kvm/hyp/nvhe/ubsan.c | 164 ++++++++++++++++++++
arch/arm64/kvm/kvm_ubsan_buffer.c | 81 ++++++++++
12 files changed, 478 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/include/asm/kvm_debug_buffer.h
create mode 100644 arch/arm64/include/asm/kvm_ubsan.h
create mode 100644 arch/arm64/kvm/hyp/include/hyp/test_ubsan.h
create mode 100644 arch/arm64/kvm/hyp/nvhe/ubsan.c
create mode 100644 arch/arm64/kvm/kvm_ubsan_buffer.c

--
2.30.0.284.gd98b1dd5eaa7-goog


2021-01-14 17:26:39

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 2/9] KVM: arm64: Add a buffer that can pass UBSan data from hyp/nVHE to kernel

From: George Popescu <[email protected]>

Share a buffer between the kernel and the hyp/nVHE code by using the
macros from kvm_debug_buffer.h.
The hyp/nVHE code requires a write index which counts how many elements
have been writtens inside the buffer and the kernel requires a read
index which counts how many elements have been read from the buffer.
The write index and the buffer are shared with the kernel in read-only.

The kvm_debug_buffer_ind returns the reading and writing points of the
circular buffer and updates the reading index.

Data collected from UBSan handlers inside hyp/nVHE is stored in the
kvm_ubsan_buffer.
This buffer stores only UBSan data because it should not be preoccupied
by other mechanisms data structures and functionalities.

Also, for the moment the buffer is mapped inside .bss, where both the kernel
and the hyp/nVHE code have Read/Write rights, but in the future this will change
and the kernel will not be able to acess hyp/nVHE's .bss. At that point the buffer
will only need to be mapped in order for this patch to work.

Change-Id: I696409db1de629b082abfe4c7f6bf066f12b539f
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/assembler.h | 11 +++++++
arch/arm64/include/asm/kvm_debug_buffer.h | 36 ++++++++++++++++++++
arch/arm64/include/asm/kvm_host.h | 8 ++++-
arch/arm64/include/asm/kvm_ubsan.h | 14 ++++++++
arch/arm64/kvm/Makefile | 2 ++
arch/arm64/kvm/arm.c | 9 +++++
arch/arm64/kvm/hyp/nvhe/host.S | 4 +++
arch/arm64/kvm/hyp/nvhe/ubsan.c | 23 +++++++++++++
arch/arm64/kvm/kvm_ubsan_buffer.c | 40 +++++++++++++++++++++++
9 files changed, 146 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/include/asm/kvm_debug_buffer.h
create mode 100644 arch/arm64/include/asm/kvm_ubsan.h
create mode 100644 arch/arm64/kvm/kvm_ubsan_buffer.c

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index bf125c591116..ebc18a8a0e1f 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -258,6 +258,17 @@ alternative_endif
ldr \dst, [\dst, \tmp]
.endm

+ /*
+ * @sym: The name of the per-cpu variable
+ * @reg: value to store
+ * @tmp1: scratch register
+ * @tmp2: scratch register
+ */
+ .macro str_this_cpu sym, reg, tmp1, tmp2
+ adr_this_cpu \tmp1, \sym, \tmp2
+ str \reg, [\tmp1]
+ .endm
+
/*
* vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
*/
diff --git a/arch/arm64/include/asm/kvm_debug_buffer.h b/arch/arm64/include/asm/kvm_debug_buffer.h
new file mode 100644
index 000000000000..e5375c2cff1a
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_debug_buffer.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Google LLC
+ * Author: George Popescu <[email protected]>
+ */
+
+#include <linux/percpu-defs.h>
+
+
+#define KVM_DEBUG_BUFFER_SIZE 1000
+
+#ifdef __KVM_NVHE_HYPERVISOR__
+#define DEFINE_KVM_DEBUG_BUFFER(type_name, buffer_name, write_ind, size)\
+ DEFINE_PER_CPU(type_name, buffer_name)[size]; \
+ DEFINE_PER_CPU(unsigned long, write_ind) = 0;
+
+#define DECLARE_KVM_DEBUG_BUFFER(type_name, buffer_name, write_ind, size)\
+ DECLARE_PER_CPU(type_name, buffer_name)[size]; \
+ DECLARE_PER_CPU(unsigned long, write_ind);
+#else
+#define DECLARE_KVM_DEBUG_BUFFER(type_name, buffer_name, write_ind, size)\
+ DECLARE_KVM_NVHE_PER_CPU(type_name, buffer_name)[size]; \
+ DECLARE_KVM_NVHE_PER_CPU(unsigned long, write_ind);
+#endif //__KVM_NVHE_HYPERVISOR__
+
+#ifdef __ASSEMBLY__
+#include <asm/assembler.h>
+
+.macro clear_buffer tmp1, tmp2, tmp3
+ mov \tmp1, 0
+#ifdef CONFIG_UBSAN
+ str_this_cpu kvm_ubsan_buff_wr_ind, \tmp1, \tmp2, \tmp3
+#endif //CONFIG_UBSAN
+.endm
+
+#endif
\ No newline at end of file
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 11beda85ee7e..385aa82c3fec 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -569,6 +569,12 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
void kvm_arm_halt_guest(struct kvm *kvm);
void kvm_arm_resume_guest(struct kvm *kvm);

+
+#ifdef CONFIG_UBSAN
+extern void __kvm_check_ubsan_buffer(void);
+#else
+static inline void __kvm_check_ubsan_buffer(void) {}
+#endif /* CONFIG_UBSAN */
#define kvm_call_hyp_nvhe(f, ...) \
({ \
struct arm_smccc_res res; \
@@ -576,7 +582,7 @@ void kvm_arm_resume_guest(struct kvm *kvm);
arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f), \
##__VA_ARGS__, &res); \
WARN_ON(res.a0 != SMCCC_RET_SUCCESS); \
- \
+ __kvm_check_ubsan_buffer(); \
res.a1; \
})

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
new file mode 100644
index 000000000000..fb32c7fd65d4
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright 2020 Google LLC
+ * Author: George Popescu <[email protected]>
+ */
+
+#include <ubsan.h>
+
+#define UBSAN_MAX_TYPE 6
+#define KVM_UBSAN_BUFFER_SIZE 1000
+
+struct kvm_ubsan_info {
+ int type;
+};
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 60fd181df624..fa3fcf3898d4 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -4,6 +4,7 @@
#

ccflags-y += -I $(srctree)/$(src)
+CFLAGS_kvm_ubsan_buffer.o += -I $(srctree)/lib/

KVM=../../../virt/kvm

@@ -24,4 +25,5 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
vgic/vgic-its.o vgic/vgic-debug.o

+kvm-$(CONFIG_UBSAN) += kvm_ubsan_buffer.o
kvm-$(CONFIG_KVM_ARM_PMU) += pmu-emul.o
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6e637d2b4cfb..ddcc180e59e9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1780,6 +1780,15 @@ static int init_hyp_mode(void)
goto out_err;
}
}
+#ifdef CONFIG_UBSAN
+ /* required by ubsan to access the handlers structures fields */
+ err = create_hyp_mappings(kvm_ksym_ref(_data),
+ kvm_ksym_ref(__end_once), PAGE_HYP_RO);
+ if (err) {
+ kvm_err("Cannot map data section\n");
+ goto out_err;
+ }
+#endif

/*
* Map Hyp percpu pages
diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S
index a820dfdc9c25..0967906265d3 100644
--- a/arch/arm64/kvm/hyp/nvhe/host.S
+++ b/arch/arm64/kvm/hyp/nvhe/host.S
@@ -8,6 +8,7 @@

#include <asm/assembler.h>
#include <asm/kvm_asm.h>
+#include <asm/kvm_debug_buffer.h>
#include <asm/kvm_mmu.h>

.text
@@ -34,6 +35,9 @@ SYM_FUNC_START(__host_exit)
/* Store the host regs x18-x29, lr */
save_callee_saved_regs x0

+ /* when entering the host clear the buffers */
+ clear_buffer x4, x5, x6
+
/* Save the host context pointer in x29 across the function call */
mov x29, x0
bl handle_trap
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index a5db6b61ceb2..8a194fb1f6cf 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -3,10 +3,33 @@
* Copyright 2020 Google LLC
* Author: George Popescu <[email protected]>
*/
+#include <linux/bitops.h>
#include <linux/ctype.h>
#include <linux/types.h>
+#include <linux/percpu-defs.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_ubsan.h>
+#include <asm/kvm_debug_buffer.h>
+#include <kvm/arm_pmu.h>
#include <ubsan.h>

+DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
+ kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
+
+static inline struct kvm_ubsan_info *kvm_ubsan_buffer_next_slot(void)
+{
+ struct kvm_ubsan_info *res = NULL;
+ unsigned long write_ind = __this_cpu_read(kvm_ubsan_buff_wr_ind);
+ if (write_ind < KVM_UBSAN_BUFFER_SIZE) {
+ res = this_cpu_ptr(&kvm_ubsan_buffer[write_ind]);
+ ++write_ind;
+ __this_cpu_write(kvm_ubsan_buff_wr_ind, write_ind);
+ }
+ return res;
+}
+
void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}

void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
new file mode 100644
index 000000000000..4a1959ba9f68
--- /dev/null
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Google LLC
+ * Author: George Popescu <[email protected]>
+ */
+
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <asm/kvm_debug_buffer.h>
+#include <asm/kvm_arm.h>
+#include <asm/kvm_asm.h>
+#include <kvm/arm_pmu.h>
+
+#include <ubsan.h>
+#include <asm/kvm_ubsan.h>
+
+DECLARE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
+ kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
+
+
+void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
+{
+ unsigned long i;
+ struct kvm_ubsan_info *slot;
+
+ slot = (struct kvm_ubsan_info *) this_cpu_ptr_nvhe_sym(kvm_ubsan_buffer);
+ for (i = left; i < right; ++i) {
+ /* check ubsan data */
+ slot[i].type = 0;
+ }
+}
+
+void __kvm_check_ubsan_buffer(void)
+{
+ unsigned long *write_ind;
+
+ write_ind = (unsigned long *) this_cpu_ptr_nvhe_sym(kvm_ubsan_buff_wr_ind);
+ iterate_kvm_ubsan_buffer(0, *write_ind);
+}
+
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:26:52

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 1/9] KVM: arm64: Enable UBSan instrumentation in nVHE hyp code

From: George-Aurelian Popescu <[email protected]>

Implement UBSan handlers inside nVHe hyp code, as empty functions for the
moment, so the undefined behaviours, that are triggered there, will be
linked to them, not to the ones defined in kernel-proper lib/ubsan.c.

In this way, enabling UBSAN_MISC won't cause a link error.

Change-Id: I4a468b33251fa099ddfc05a7cefa520cb8817994
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/kvm/hyp/nvhe/Makefile | 3 ++-
arch/arm64/kvm/hyp/nvhe/ubsan.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kvm/hyp/nvhe/ubsan.c

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 1f1e351c5fe2..2a683e7c6c5b 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -10,6 +10,8 @@ obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
hyp-main.o hyp-smp.o psci-relay.o
obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
../fpsimd.o ../hyp-entry.o ../exception.o
+obj-$(CONFIG_UBSAN) += ubsan.o
+CFLAGS_ubsan.nvhe.o += -I $(srctree)/lib/

##
## Build rules for compiling nVHE hyp code
@@ -61,7 +63,6 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS), $(KBUILD_CFLAG
# cause crashes. Just disable it.
GCOV_PROFILE := n
KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
KCOV_INSTRUMENT := n

# Skip objtool checking for this directory because nVHE code is compiled with
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
new file mode 100644
index 000000000000..a5db6b61ceb2
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 Google LLC
+ * Author: George Popescu <[email protected]>
+ */
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <ubsan.h>
+
+void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}
+
+void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
+
+void __ubsan_handle_mul_overflow(void *_data, void *lhs, void *rhs) {}
+
+void __ubsan_handle_negate_overflow(void *_data, void *old_val) {}
+
+void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) {}
+
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr) {}
+
+void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}
+
+void __ubsan_handle_out_of_bounds(void *_data, void *index) {}
+
+void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}
+
+void __ubsan_handle_builtin_unreachable(void *_data) {}
+
+void __ubsan_handle_load_invalid_value(void *_data, void *val) {}
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:27:37

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 6/9] KVM: arm64: __ubsan_handle_load_invalid_value EL2 implementation.

From: George Popescu <[email protected]>

The handler for the load invalid value undefined behaviour is
implemented at EL2. The EL2 handler's parameters are stored inside the buffer.
They are used by the symetric handler from EL1.

Signed-off-by: George Popescu <[email protected]>
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 5 ++++-
arch/arm64/kvm/hyp/nvhe/ubsan.c | 14 +++++++++++++-
arch/arm64/kvm/kvm_ubsan_buffer.c | 6 +++++-
3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index 0eef0e11a93b..95ac6728ffd1 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -20,12 +20,14 @@ struct kvm_ubsan_info {
enum {
UBSAN_OUT_OF_BOUNDS,
UBSAN_UNREACHABLE_DATA,
- UBSAN_SHIFT_OUT_OF_BOUNDS
+ UBSAN_SHIFT_OUT_OF_BOUNDS,
+ UBSAN_INVALID_DATA
} type;
union {
struct out_of_bounds_data out_of_bounds_data;
struct unreachable_data unreachable_data;
struct shift_out_of_bounds_data shift_out_of_bounds_data;
+ struct invalid_value_data invalid_value_data;
};
union {
struct ubsan_values u_val;
@@ -35,3 +37,4 @@ struct kvm_ubsan_info {
void __ubsan_handle_out_of_bounds(void *_data, void *index);
void __ubsan_handle_builtin_unreachable(void *_data);
void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
+void __ubsan_handle_load_invalid_value(void *_data, void *val);
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index 1069ed5036d5..3143f7722be2 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -82,4 +82,16 @@ void __ubsan_handle_builtin_unreachable(void *_data)
}
}

-void __ubsan_handle_load_invalid_value(void *_data, void *val) {}
+void __ubsan_handle_load_invalid_value(void *_data, void *val)
+{
+ struct kvm_ubsan_info *slot;
+ struct invalid_value_data *data = _data;
+
+ slot = kvm_ubsan_buffer_next_slot();
+ if (slot) {
+ slot->type = UBSAN_INVALID_DATA;
+ slot->invalid_value_data = *data;
+ slot->u_val.lval = val;
+ }
+
+}
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index b80045883047..5439f7a91636 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -31,7 +31,11 @@ void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
__ubsan_handle_shift_out_of_bounds(&slot->shift_out_of_bounds_data,
slot->u_val.lval, slot->u_val.rval);
break;
- }
+ case UBSAN_INVALID_DATA:
+ __ubsan_handle_load_invalid_value(&slot->invalid_value_data,
+ slot->u_val.lval);
+ break;
+ }
}

void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:27:43

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 3/9] KVM: arm64: Enable UBSAN_BOUNDS for the both the kernel and hyp/nVHE

From: George Popescu <[email protected]>

If an out of bounds happens inside the hyp/nVHE code, the ubsan_out_of_bounds
handler stores the logging data inside the kvm_ubsan_buffer. The one responsible
for printing is the kernel ubsan_out_of_bounds handler. The process of
decapsulating the data from the buffer is straightforward.

Signed-off-by: George Popescu <[email protected]>
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 19 ++++++++++++++++++-
arch/arm64/kvm/hyp/nvhe/ubsan.c | 14 ++++++++++++--
arch/arm64/kvm/kvm_ubsan_buffer.c | 10 ++++++++++
3 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index fb32c7fd65d4..4f471acb88b0 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -9,6 +9,23 @@
#define UBSAN_MAX_TYPE 6
#define KVM_UBSAN_BUFFER_SIZE 1000

+
+struct ubsan_values {
+ void *lval;
+ void *rval;
+ char op;
+};
+
struct kvm_ubsan_info {
- int type;
+ enum {
+ UBSAN_OUT_OF_BOUNDS,
+ } type;
+ union {
+ struct out_of_bounds_data out_of_bounds_data;
+ };
+ union {
+ struct ubsan_values u_val;
+ };
};
+
+void __ubsan_handle_out_of_bounds(void *_data, void *index);
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index 8a194fb1f6cf..55a8f6db8555 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -13,7 +13,6 @@
#include <asm/kvm_ubsan.h>
#include <asm/kvm_debug_buffer.h>
#include <kvm/arm_pmu.h>
-#include <ubsan.h>

DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
@@ -44,7 +43,18 @@ void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr) {}

void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}

-void __ubsan_handle_out_of_bounds(void *_data, void *index) {}
+void __ubsan_handle_out_of_bounds(void *_data, void *index)
+{
+ struct kvm_ubsan_info *slot;
+ struct out_of_bounds_data *data = _data;
+
+ slot = kvm_ubsan_buffer_next_slot();
+ if (slot) {
+ slot->type = UBSAN_OUT_OF_BOUNDS;
+ slot->out_of_bounds_data = *data;
+ slot->u_val.lval = index;
+ }
+}

void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}

diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index 4a1959ba9f68..a1523f86be3c 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -17,6 +17,15 @@
DECLARE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);

+void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
+{
+ switch (slot->type) {
+ case UBSAN_OUT_OF_BOUNDS:
+ __ubsan_handle_out_of_bounds(&slot->out_of_bounds_data,
+ slot->u_val.lval);
+ break;
+ }
+}

void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
{
@@ -26,6 +35,7 @@ void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
slot = (struct kvm_ubsan_info *) this_cpu_ptr_nvhe_sym(kvm_ubsan_buffer);
for (i = left; i < right; ++i) {
/* check ubsan data */
+ __kvm_check_ubsan_data(slot + i);
slot[i].type = 0;
}
}
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:28:07

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 7/9] KVM: arm64: Detect type mismatch undefined behaviour from hyp/nVHE code

From: George Popescu <[email protected]>

Type mismatch undefiend behaviour handler provides two handlers with two
data structures type_mismatch_data and type_mismatch_data_v1. Both can be
stored inside a common data structure: type_mismatch_data_common, which
differs of type_mismatch_data only by keeping a pointer to a
struct source_location.
In this way, the buffer keeps the data encapsulated inside of a struct
type_mismatch_data, because pointers from nVHE can not be passed to the
kernel.

Inside the kernel call the __ubsan_handle_type_mismatch_data with the
data from the buffer.

Signed-off-by: George Popescu <[email protected]>
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 6 ++++-
arch/arm64/kvm/hyp/nvhe/ubsan.c | 41 ++++++++++++++++++++++++++++--
arch/arm64/kvm/kvm_ubsan_buffer.c | 5 +++-
3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index 95ac6728ffd1..93c1b695097a 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -21,13 +21,15 @@ struct kvm_ubsan_info {
UBSAN_OUT_OF_BOUNDS,
UBSAN_UNREACHABLE_DATA,
UBSAN_SHIFT_OUT_OF_BOUNDS,
- UBSAN_INVALID_DATA
+ UBSAN_INVALID_DATA,
+ UBSAN_TYPE_MISMATCH
} type;
union {
struct out_of_bounds_data out_of_bounds_data;
struct unreachable_data unreachable_data;
struct shift_out_of_bounds_data shift_out_of_bounds_data;
struct invalid_value_data invalid_value_data;
+ struct type_mismatch_data type_mismatch_data;
};
union {
struct ubsan_values u_val;
@@ -38,3 +40,5 @@ void __ubsan_handle_out_of_bounds(void *_data, void *index);
void __ubsan_handle_builtin_unreachable(void *_data);
void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
void __ubsan_handle_load_invalid_value(void *_data, void *val);
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *_data, void *ptr);
+
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index 3143f7722be2..a9f72d4bcab7 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -29,6 +29,24 @@ static inline struct kvm_ubsan_info *kvm_ubsan_buffer_next_slot(void)
return res;
}

+static void write_type_mismatch_data(struct type_mismatch_data_common *data, void *lval)
+{
+ struct kvm_ubsan_info *slot;
+ struct type_mismatch_data *aux_cont;
+
+ slot = kvm_ubsan_buffer_next_slot();
+ if (slot) {
+ slot->type = UBSAN_TYPE_MISMATCH;
+ aux_cont = &slot->type_mismatch_data;
+ aux_cont->location.file_name = data->location->file_name;
+ aux_cont->location.reported = data->location->reported;
+ aux_cont->type = data->type;
+ aux_cont->alignment = data->alignment;
+ aux_cont->type_check_kind = data->type_check_kind;
+ slot->u_val.lval = lval;
+ }
+}
+
void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}

void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
@@ -39,9 +57,28 @@ void __ubsan_handle_negate_overflow(void *_data, void *old_val) {}

void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) {}

-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr) {}
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr)
+{
+ struct type_mismatch_data_common common_data = {
+ .location = &data->location,
+ .type = data->type,
+ .alignment = data->alignment,
+ .type_check_kind = data->type_check_kind
+ };
+ write_type_mismatch_data(&common_data, ptr);
+}

-void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}
+void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr)
+{
+ struct type_mismatch_data_v1 *data = _data;
+ struct type_mismatch_data_common common_data = {
+ .location = &data->location,
+ .type = data->type,
+ .alignment = 1UL << data->log_alignment,
+ .type_check_kind = data->type_check_kind
+ };
+ write_type_mismatch_data(&common_data, ptr);
+}

void __ubsan_handle_out_of_bounds(void *_data, void *index)
{
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index 5439f7a91636..b7823dedf8b1 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -35,6 +35,10 @@ void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
__ubsan_handle_load_invalid_value(&slot->invalid_value_data,
slot->u_val.lval);
break;
+ case UBSAN_TYPE_MISMATCH:
+ __ubsan_handle_type_mismatch(&slot->type_mismatch_data,
+ slot->u_val.lval);
+ break;
}
}

@@ -58,4 +62,3 @@ void __kvm_check_ubsan_buffer(void)
write_ind = (unsigned long *) this_cpu_ptr_nvhe_sym(kvm_ubsan_buff_wr_ind);
iterate_kvm_ubsan_buffer(0, *write_ind);
}
-
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:28:08

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 5/9] KVM: arm64: Enable shift out of bounds undefined behaviour check for hyp/nVHE

From: George Popescu <[email protected]>

__ubsan_handle_shift_out_of_bounds data is passed to the buffer inside
hyp/nVHE. This data is passed to the original handler from kernel.

The 64bit values of the shift expression operands are stored as the lhs
and rhs pointers, so there is no need to dereference them.

Signed-off-by: George Popescu <[email protected]>
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 5 ++++-
arch/arm64/kvm/hyp/nvhe/ubsan.c | 14 +++++++++++++-
arch/arm64/kvm/kvm_ubsan_buffer.c | 4 ++++
3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index 70c6f2541d07..0eef0e11a93b 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -19,11 +19,13 @@ struct ubsan_values {
struct kvm_ubsan_info {
enum {
UBSAN_OUT_OF_BOUNDS,
- UBSAN_UNREACHABLE_DATA
+ UBSAN_UNREACHABLE_DATA,
+ UBSAN_SHIFT_OUT_OF_BOUNDS
} type;
union {
struct out_of_bounds_data out_of_bounds_data;
struct unreachable_data unreachable_data;
+ struct shift_out_of_bounds_data shift_out_of_bounds_data;
};
union {
struct ubsan_values u_val;
@@ -32,3 +34,4 @@ struct kvm_ubsan_info {

void __ubsan_handle_out_of_bounds(void *_data, void *index);
void __ubsan_handle_builtin_unreachable(void *_data);
+void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index 5e55897b2d72..1069ed5036d5 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -56,7 +56,19 @@ void __ubsan_handle_out_of_bounds(void *_data, void *index)
}
}

-void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}
+void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs)
+{
+ struct kvm_ubsan_info *slot;
+ struct shift_out_of_bounds_data *data = _data;
+
+ slot = kvm_ubsan_buffer_next_slot();
+ if (slot) {
+ slot->type = UBSAN_SHIFT_OUT_OF_BOUNDS;
+ slot->shift_out_of_bounds_data = *data;
+ slot->u_val.lval = lhs;
+ slot->u_val.rval = rhs;
+ }
+}

void __ubsan_handle_builtin_unreachable(void *_data)
{
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index e51949c275aa..b80045883047 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -27,6 +27,10 @@ void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
case UBSAN_UNREACHABLE_DATA:
__ubsan_handle_builtin_unreachable(&slot->unreachable_data);
break;
+ case UBSAN_SHIFT_OUT_OF_BOUNDS:
+ __ubsan_handle_shift_out_of_bounds(&slot->shift_out_of_bounds_data,
+ slot->u_val.lval, slot->u_val.rval);
+ break;
}
}

--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:28:19

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 4/9] KVM: arm64: Enable UBsan check for unreachable code inside hyp/nVHE code

From: George Popescu <[email protected]>

The data from __ubsan_handle_builtin_unreachable is passed to the buffer
and printed inside the kernel by its simetric handler.

Signed-off-by: George Popescu <[email protected]>
Change-Id: I71d789b7f4ec3d4c787012a061b7f5d7952cee19
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 3 +++
arch/arm64/kvm/hyp/nvhe/ubsan.c | 12 +++++++++++-
arch/arm64/kvm/kvm_ubsan_buffer.c | 3 +++
3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index 4f471acb88b0..70c6f2541d07 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -19,9 +19,11 @@ struct ubsan_values {
struct kvm_ubsan_info {
enum {
UBSAN_OUT_OF_BOUNDS,
+ UBSAN_UNREACHABLE_DATA
} type;
union {
struct out_of_bounds_data out_of_bounds_data;
+ struct unreachable_data unreachable_data;
};
union {
struct ubsan_values u_val;
@@ -29,3 +31,4 @@ struct kvm_ubsan_info {
};

void __ubsan_handle_out_of_bounds(void *_data, void *index);
+void __ubsan_handle_builtin_unreachable(void *_data);
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index 55a8f6db8555..5e55897b2d72 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -58,6 +58,16 @@ void __ubsan_handle_out_of_bounds(void *_data, void *index)

void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}

-void __ubsan_handle_builtin_unreachable(void *_data) {}
+void __ubsan_handle_builtin_unreachable(void *_data)
+{
+ struct kvm_ubsan_info *slot;
+ struct unreachable_data *data = _data;
+
+ slot = kvm_ubsan_buffer_next_slot();
+ if (slot) {
+ slot->type = UBSAN_UNREACHABLE_DATA;
+ slot->unreachable_data = *data;
+ }
+}

void __ubsan_handle_load_invalid_value(void *_data, void *val) {}
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index a1523f86be3c..e51949c275aa 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -24,6 +24,9 @@ void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
__ubsan_handle_out_of_bounds(&slot->out_of_bounds_data,
slot->u_val.lval);
break;
+ case UBSAN_UNREACHABLE_DATA:
+ __ubsan_handle_builtin_unreachable(&slot->unreachable_data);
+ break;
}
}

--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:28:24

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 8/9] KVM: arm64: Detect arithmetic overflow is inside hyp/nVHE.

From: George Popescu <[email protected]>

Whenever an arithmetic overflow: addition, substraction, multiplication,
division or negating happens inside the hyp/nVHE code,
an __ubsan_handle_*_overflow is called.

All the overflow handlers are sharing the same structure called
overflow_data.

Signed-off-by: George Popescu <[email protected]>
Change-Id: Iec1ef331e471efbb35a39ffaee0641107a3a0e3a
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/kvm_ubsan.h | 10 ++++++--
arch/arm64/kvm/hyp/nvhe/ubsan.c | 40 ++++++++++++++++++++++++++----
arch/arm64/kvm/kvm_ubsan_buffer.c | 20 ++++++++++++++-
3 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index 93c1b695097a..da4a3b4e28e0 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -22,7 +22,8 @@ struct kvm_ubsan_info {
UBSAN_UNREACHABLE_DATA,
UBSAN_SHIFT_OUT_OF_BOUNDS,
UBSAN_INVALID_DATA,
- UBSAN_TYPE_MISMATCH
+ UBSAN_TYPE_MISMATCH,
+ UBSAN_OVERFLOW_DATA
} type;
union {
struct out_of_bounds_data out_of_bounds_data;
@@ -30,6 +31,7 @@ struct kvm_ubsan_info {
struct shift_out_of_bounds_data shift_out_of_bounds_data;
struct invalid_value_data invalid_value_data;
struct type_mismatch_data type_mismatch_data;
+ struct overflow_data overflow_data;
};
union {
struct ubsan_values u_val;
@@ -41,4 +43,8 @@ void __ubsan_handle_builtin_unreachable(void *_data);
void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
void __ubsan_handle_load_invalid_value(void *_data, void *val);
void __ubsan_handle_type_mismatch(struct type_mismatch_data *_data, void *ptr);
-
+void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_negate_overflow(void *_data, void *old_val);
+void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
diff --git a/arch/arm64/kvm/hyp/nvhe/ubsan.c b/arch/arm64/kvm/hyp/nvhe/ubsan.c
index a9f72d4bcab7..f16842ff7316 100644
--- a/arch/arm64/kvm/hyp/nvhe/ubsan.c
+++ b/arch/arm64/kvm/hyp/nvhe/ubsan.c
@@ -47,15 +47,45 @@ static void write_type_mismatch_data(struct type_mismatch_data_common *data, voi
}
}

-void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}
+static void write_overflow_data(struct overflow_data *data, void *lval, void *rval, char op)
+{
+ struct kvm_ubsan_info *slot = kvm_ubsan_buffer_next_slot();
+
+ if (slot) {
+ slot->type = UBSAN_OVERFLOW_DATA;
+ slot->overflow_data = *data;
+ slot->u_val.op = op;
+ slot->u_val.lval = lval;
+ if (op != '!')
+ slot->u_val.rval = rval;
+ }
+}
+
+void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs)
+{
+ write_overflow_data(_data, lhs, rhs, '+');
+}

-void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
+void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs)
+{
+ write_overflow_data(_data, lhs, rhs, '-');
+}

-void __ubsan_handle_mul_overflow(void *_data, void *lhs, void *rhs) {}
+void __ubsan_handle_mul_overflow(void *_data, void *lhs, void *rhs)
+{
+ write_overflow_data(_data, lhs, rhs, '*');
+}

-void __ubsan_handle_negate_overflow(void *_data, void *old_val) {}
+void __ubsan_handle_negate_overflow(void *_data, void *old_val)
+{
+ write_overflow_data(_data, old_val, NULL, '!');
+}
+
+void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
+{
+ write_overflow_data(_data, lhs, rhs, '/');
+}

-void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) {}

void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr)
{
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index b7823dedf8b1..2c7060cbb48b 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -39,7 +39,25 @@ void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
__ubsan_handle_type_mismatch(&slot->type_mismatch_data,
slot->u_val.lval);
break;
- }
+ case UBSAN_OVERFLOW_DATA:
+ if (slot->u_val.op == '/') {
+ __ubsan_handle_divrem_overflow(&slot->overflow_data,
+ slot->u_val.lval, slot->u_val.rval);
+ } else if (slot->u_val.op == '!') {
+ __ubsan_handle_negate_overflow(&slot->overflow_data,
+ slot->u_val.lval);
+ } else if (slot->u_val.op == '+') {
+ __ubsan_handle_add_overflow(&slot->overflow_data,
+ slot->u_val.lval, slot->u_val.rval);
+ } else if (slot->u_val.op == '-') {
+ __ubsan_handle_sub_overflow(&slot->overflow_data,
+ slot->u_val.lval, slot->u_val.rval);
+ } else if (slot->u_val.op == '*') {
+ __ubsan_handle_mul_overflow(&slot->overflow_data,
+ slot->u_val.lval, slot->u_val.rval);
+ }
+ break;
+ }
}

void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-14 17:30:24

by Elena Petrova

[permalink] [raw]
Subject: [PATCH v2 9/9] KVM: arm64: Add UBSan tests for PKVM.

From: George-Aurelian Popescu <[email protected]>

Test the UBsan functionality inside hyp/nVHE.
Because modules are not supported inside of hyp/nVHE code, the default
testing module for UBSan can not be used.
New functions have to be defined inside of hyp/nVHE.
They are called in kvm_get_mdcr_el2, to test UBSAN whenever a VM starts.

Change-Id: Icf998da0af023c74d45be90788ac9f694e61c97c
Signed-off-by: Elena Petrova <[email protected]>
---
arch/arm64/include/asm/assembler.h | 17 ++-
arch/arm64/include/asm/kvm_debug_buffer.h | 10 +-
arch/arm64/include/asm/kvm_ubsan.h | 2 +-
arch/arm64/kvm/hyp/include/hyp/test_ubsan.h | 112 ++++++++++++++++++++
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 3 +
arch/arm64/kvm/kvm_ubsan_buffer.c | 1 -
6 files changed, 128 insertions(+), 17 deletions(-)
create mode 100644 arch/arm64/kvm/hyp/include/hyp/test_ubsan.h

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index ebc18a8a0e1f..8422b0d925e8 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -259,16 +259,15 @@ alternative_endif
.endm

/*
- * @sym: The name of the per-cpu variable
- * @reg: value to store
- * @tmp1: scratch register
- * @tmp2: scratch register
- */
- .macro str_this_cpu sym, reg, tmp1, tmp2
- adr_this_cpu \tmp1, \sym, \tmp2
+ * @sym: The name of the per-cpu variable
+ * @reg: value to store
+ * @tmp1: scratch register
+ * @tmp2: scratch register
+ */
+ .macro str_this_cpu sym, reg, tmp1, tmp2
+ adr_this_cpu \tmp1, \sym, \tmp2
str \reg, [\tmp1]
- .endm
-
+ .endm
/*
* vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
*/
diff --git a/arch/arm64/include/asm/kvm_debug_buffer.h b/arch/arm64/include/asm/kvm_debug_buffer.h
index e5375c2cff1a..361b473bb004 100644
--- a/arch/arm64/include/asm/kvm_debug_buffer.h
+++ b/arch/arm64/include/asm/kvm_debug_buffer.h
@@ -3,10 +3,8 @@
* Copyright 2020 Google LLC
* Author: George Popescu <[email protected]>
*/
-
#include <linux/percpu-defs.h>

-
#define KVM_DEBUG_BUFFER_SIZE 1000

#ifdef __KVM_NVHE_HYPERVISOR__
@@ -20,17 +18,17 @@
#else
#define DECLARE_KVM_DEBUG_BUFFER(type_name, buffer_name, write_ind, size)\
DECLARE_KVM_NVHE_PER_CPU(type_name, buffer_name)[size]; \
- DECLARE_KVM_NVHE_PER_CPU(unsigned long, write_ind);
+ DECLARE_KVM_NVHE_PER_CPU(unsigned long, write_ind);
#endif //__KVM_NVHE_HYPERVISOR__

#ifdef __ASSEMBLY__
#include <asm/assembler.h>

.macro clear_buffer tmp1, tmp2, tmp3
- mov \tmp1, 0
+ mov \tmp1, 0
#ifdef CONFIG_UBSAN
- str_this_cpu kvm_ubsan_buff_wr_ind, \tmp1, \tmp2, \tmp3
+ str_this_cpu kvm_ubsan_buff_wr_ind, \tmp1, \tmp2, \tmp3
#endif //CONFIG_UBSAN
.endm

-#endif
\ No newline at end of file
+#endif
diff --git a/arch/arm64/include/asm/kvm_ubsan.h b/arch/arm64/include/asm/kvm_ubsan.h
index da4a3b4e28e0..0b8bed08d48e 100644
--- a/arch/arm64/include/asm/kvm_ubsan.h
+++ b/arch/arm64/include/asm/kvm_ubsan.h
@@ -9,7 +9,6 @@
#define UBSAN_MAX_TYPE 6
#define KVM_UBSAN_BUFFER_SIZE 1000

-
struct ubsan_values {
void *lval;
void *rval;
@@ -18,6 +17,7 @@ struct ubsan_values {

struct kvm_ubsan_info {
enum {
+ UBSAN_NONE,
UBSAN_OUT_OF_BOUNDS,
UBSAN_UNREACHABLE_DATA,
UBSAN_SHIFT_OUT_OF_BOUNDS,
diff --git a/arch/arm64/kvm/hyp/include/hyp/test_ubsan.h b/arch/arm64/kvm/hyp/include/hyp/test_ubsan.h
new file mode 100644
index 000000000000..07759c0d1e0e
--- /dev/null
+++ b/arch/arm64/kvm/hyp/include/hyp/test_ubsan.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/ctype.h>
+
+typedef void(*test_ubsan_fp)(void);
+
+static void test_ubsan_add_overflow(void)
+{
+ volatile int val = INT_MAX;
+
+ val += 2;
+}
+
+static void test_ubsan_sub_overflow(void)
+{
+ volatile int val = INT_MIN;
+ volatile int val2 = 2;
+
+ val -= val2;
+}
+
+static void test_ubsan_mul_overflow(void)
+{
+ volatile int val = INT_MAX / 2;
+
+ val *= 3;
+}
+
+static void test_ubsan_negate_overflow(void)
+{
+ volatile int val = INT_MIN;
+
+ val = -val;
+}
+
+static void test_ubsan_divrem_overflow(void)
+{
+ volatile int val = 16;
+ volatile int val2 = 0;
+
+ val /= val2;
+}
+
+static void test_ubsan_shift_out_of_bounds(void)
+{
+ volatile int val = -1;
+ int val2 = 10;
+
+ val2 <<= val;
+}
+
+static void test_ubsan_out_of_bounds(void)
+{
+ volatile int i = 4, j = 5;
+ volatile int arr[4];
+
+ arr[j] = i;
+}
+
+static void test_ubsan_load_invalid_value(void)
+{
+ volatile char *dst, *src;
+ bool val, val2, *ptr;
+ char c = 4;
+
+ dst = (char *)&val;
+ src = &c;
+ *dst = *src;
+
+ ptr = &val2;
+ val2 = val;
+}
+
+static void test_ubsan_misaligned_access(void)
+{
+ volatile char arr[5] __aligned(4) = {1, 2, 3, 4, 5};
+ volatile int *ptr, val = 6;
+
+ ptr = (int *)(arr + 1);
+ *ptr = val;
+}
+
+static void test_ubsan_object_size_mismatch(void)
+{
+ /* "((aligned(8)))" helps this not into be misaligned for ptr-access. */
+ volatile int val __aligned(8) = 4;
+ volatile long long *ptr, val2;
+
+ ptr = (long long *)&val;
+ val2 = *ptr;
+}
+
+static const test_ubsan_fp test_ubsan_array[] = {
+ test_ubsan_out_of_bounds,
+ test_ubsan_add_overflow,
+ test_ubsan_sub_overflow,
+ test_ubsan_mul_overflow,
+ test_ubsan_negate_overflow,
+ test_ubsan_divrem_overflow,
+ test_ubsan_shift_out_of_bounds,
+ test_ubsan_load_invalid_value,
+ test_ubsan_misaligned_access,
+ test_ubsan_object_size_mismatch,
+};
+
+static void test_ubsan(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(test_ubsan_array); i++)
+ test_ubsan_array[i]();
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index bde658d51404..459f5ebe5e18 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -13,6 +13,7 @@
#include <asm/kvm_mmu.h>

#include <nvhe/trap_handler.h>
+#include <hyp/test_ubsan.h>

DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);

@@ -90,6 +91,8 @@ static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt)
static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt)
{
cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2();
+ if (IS_ENABLED(CONFIG_TEST_UBSAN))
+ test_ubsan();
}

static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/kvm_ubsan_buffer.c b/arch/arm64/kvm/kvm_ubsan_buffer.c
index 2c7060cbb48b..49bedc9de139 100644
--- a/arch/arm64/kvm/kvm_ubsan_buffer.c
+++ b/arch/arm64/kvm/kvm_ubsan_buffer.c
@@ -11,7 +11,6 @@
#include <asm/kvm_asm.h>
#include <kvm/arm_pmu.h>

-#include <ubsan.h>
#include <asm/kvm_ubsan.h>

DECLARE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
--
2.30.0.284.gd98b1dd5eaa7-goog

2021-01-15 08:56:59

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 1/9] KVM: arm64: Enable UBSan instrumentation in nVHE hyp code

Hi Elena,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on v5.11-rc3 next-20210115]
[cannot apply to kvmarm/next soc/for-next arm/for-next xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/9eaabf22215aee1257362a608a15658c558d7fe5
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
git checkout 9eaabf22215aee1257362a608a15658c558d7fe5
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

arch/arm64/kvm/hyp/nvhe/ubsan.c:10:6: warning: no previous prototype for '__ubsan_handle_add_overflow' [-Wmissing-prototypes]
10 | void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:12:6: warning: no previous prototype for '__ubsan_handle_sub_overflow' [-Wmissing-prototypes]
12 | void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:14:6: warning: no previous prototype for '__ubsan_handle_mul_overflow' [-Wmissing-prototypes]
14 | void __ubsan_handle_mul_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:16:6: warning: no previous prototype for '__ubsan_handle_negate_overflow' [-Wmissing-prototypes]
16 | void __ubsan_handle_negate_overflow(void *_data, void *old_val) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:18:6: warning: no previous prototype for '__ubsan_handle_divrem_overflow' [-Wmissing-prototypes]
18 | void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:20:6: warning: no previous prototype for '__ubsan_handle_type_mismatch' [-Wmissing-prototypes]
20 | void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> arch/arm64/kvm/hyp/nvhe/ubsan.c:22:6: warning: no previous prototype for '__ubsan_handle_type_mismatch_v1' [-Wmissing-prototypes]
22 | void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:24:6: warning: no previous prototype for '__ubsan_handle_out_of_bounds' [-Wmissing-prototypes]
24 | void __ubsan_handle_out_of_bounds(void *_data, void *index) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:26:6: warning: no previous prototype for '__ubsan_handle_shift_out_of_bounds' [-Wmissing-prototypes]
26 | void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:28:6: warning: no previous prototype for '__ubsan_handle_builtin_unreachable' [-Wmissing-prototypes]
28 | void __ubsan_handle_builtin_unreachable(void *_data) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:30:6: warning: no previous prototype for '__ubsan_handle_load_invalid_value' [-Wmissing-prototypes]
30 | void __ubsan_handle_load_invalid_value(void *_data, void *val) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/__ubsan_handle_type_mismatch_v1 +22 arch/arm64/kvm/hyp/nvhe/ubsan.c

21
> 22 void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}
23

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (4.60 kB)
.config.gz (74.69 kB)
Download all attachments

2021-01-15 09:57:59

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 2/9] KVM: arm64: Add a buffer that can pass UBSan data from hyp/nVHE to kernel

Hi Elena,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[cannot apply to kvmarm/next soc/for-next arm/for-next xlnx/master v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/aba3219bbab3bb5c7f037fe7b6c6c783942bc954
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
git checkout aba3219bbab3bb5c7f037fe7b6c6c783942bc954
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from arch/arm64/kvm/kvm_ubsan_buffer.c:12:
>> include/kvm/arm_pmu.h:52:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
52 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:54:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
54 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:56:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
56 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
>> arch/arm64/kvm/kvm_ubsan_buffer.c:21:6: warning: no previous prototype for 'iterate_kvm_ubsan_buffer' [-Wmissing-prototypes]
21 | void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> arch/arm64/kvm/kvm_ubsan_buffer.c:33:6: warning: no previous prototype for '__kvm_check_ubsan_buffer' [-Wmissing-prototypes]
33 | void __kvm_check_ubsan_buffer(void)
| ^~~~~~~~~~~~~~~~~~~~~~~~


vim +52 include/kvm/arm_pmu.h

ab9468340d2bcc2a Shannon Zhao 2015-06-18 31
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 32 #define kvm_arm_pmu_irq_initialized(v) ((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
051ff581ce70e822 Shannon Zhao 2015-12-08 33 u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
051ff581ce70e822 Shannon Zhao 2015-12-08 34 void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
96b0eebcc6a14e3b Shannon Zhao 2015-09-08 35 u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu);
88865beca90621ae Marc Zyngier 2020-03-12 36 u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1);
bca031e2c8aa22a9 Zenghui Yu 2019-07-18 37 void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu);
2aa36e9840d71710 Shannon Zhao 2015-09-11 38 void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
5f0a714a2b63c25f Shannon Zhao 2015-09-11 39 void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu);
418e5ca88cc18b7e Andrew Murray 2019-06-17 40 void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val);
418e5ca88cc18b7e Andrew Murray 2019-06-17 41 void kvm_pmu_enable_counter_mask(struct kvm_vcpu *vcpu, u64 val);
b02386eb7dac7555 Shannon Zhao 2016-02-26 42 void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu);
b02386eb7dac7555 Shannon Zhao 2016-02-26 43 void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu);
3dbbdf78636e6609 Christoffer Dall 2017-02-01 44 bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu);
3dbbdf78636e6609 Christoffer Dall 2017-02-01 45 void kvm_pmu_update_run(struct kvm_vcpu *vcpu);
7a0adc7064b88609 Shannon Zhao 2015-09-08 46 void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val);
76993739cd6f5b42 Shannon Zhao 2015-10-28 47 void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val);
7f7663587165fe1a Shannon Zhao 2015-07-03 48 void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
7f7663587165fe1a Shannon Zhao 2015-07-03 49 u64 select_idx);
808e738142e7086e Shannon Zhao 2016-01-11 50 bool kvm_arm_support_pmu_v3(void);
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 51 int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 @52 struct kvm_device_attr *attr);
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 53 int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 54 struct kvm_device_attr *attr);
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 55 int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
bb0c70bcca6ba3c8 Shannon Zhao 2016-01-11 56 struct kvm_device_attr *attr);
a2befacf50940017 Christoffer Dall 2017-05-02 57 int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
04fe472615d0216e Shannon Zhao 2015-09-11 58 #else
04fe472615d0216e Shannon Zhao 2015-09-11 59 struct kvm_pmu {
04fe472615d0216e Shannon Zhao 2015-09-11 60 };
ab9468340d2bcc2a Shannon Zhao 2015-06-18 61

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (5.82 kB)
.config.gz (74.69 kB)
Download all attachments

2021-01-15 12:47:59

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 2/9] KVM: arm64: Add a buffer that can pass UBSan data from hyp/nVHE to kernel

Hi Elena,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on arm64/for-next/core]
[cannot apply to kvmarm/next soc/for-next arm/for-next xlnx/master v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/aba3219bbab3bb5c7f037fe7b6c6c783942bc954
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
git checkout aba3219bbab3bb5c7f037fe7b6c6c783942bc954
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from arch/arm64/kvm/hyp/nvhe/ubsan.c:9:
>> arch/arm64/kvm/hyp/nvhe/ubsan.c:18:48: error: conflicting types for 'kvm_ubsan_buffer'
18 | DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
| ^~~~~~~~~~~~~~~~
include/linux/percpu-defs.h:95:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
95 | __PCPU_ATTRS(sec) __weak __typeof__(type) name
| ^~~~
arch/arm64/include/asm/kvm_debug_buffer.h:14:2: note: in expansion of macro 'DEFINE_PER_CPU'
14 | DEFINE_PER_CPU(type_name, buffer_name)[size]; \
| ^~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:18:1: note: in expansion of macro 'DEFINE_KVM_DEBUG_BUFFER'
18 | DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:18:48: note: previous declaration of 'kvm_ubsan_buffer' was here
18 | DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
| ^~~~~~~~~~~~~~~~
include/linux/percpu-defs.h:94:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
94 | extern __PCPU_ATTRS(sec) __typeof__(type) name; \
| ^~~~
arch/arm64/include/asm/kvm_debug_buffer.h:14:2: note: in expansion of macro 'DEFINE_PER_CPU'
14 | DEFINE_PER_CPU(type_name, buffer_name)[size]; \
| ^~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:18:1: note: in expansion of macro 'DEFINE_KVM_DEBUG_BUFFER'
18 | DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:33:6: warning: no previous prototype for '__ubsan_handle_add_overflow' [-Wmissing-prototypes]
33 | void __ubsan_handle_add_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:35:6: warning: no previous prototype for '__ubsan_handle_sub_overflow' [-Wmissing-prototypes]
35 | void __ubsan_handle_sub_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:37:6: warning: no previous prototype for '__ubsan_handle_mul_overflow' [-Wmissing-prototypes]
37 | void __ubsan_handle_mul_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:39:6: warning: no previous prototype for '__ubsan_handle_negate_overflow' [-Wmissing-prototypes]
39 | void __ubsan_handle_negate_overflow(void *_data, void *old_val) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:41:6: warning: no previous prototype for '__ubsan_handle_divrem_overflow' [-Wmissing-prototypes]
41 | void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:43:6: warning: no previous prototype for '__ubsan_handle_type_mismatch' [-Wmissing-prototypes]
43 | void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:45:6: warning: no previous prototype for '__ubsan_handle_type_mismatch_v1' [-Wmissing-prototypes]
45 | void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:47:6: warning: no previous prototype for '__ubsan_handle_out_of_bounds' [-Wmissing-prototypes]
47 | void __ubsan_handle_out_of_bounds(void *_data, void *index) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:49:6: warning: no previous prototype for '__ubsan_handle_shift_out_of_bounds' [-Wmissing-prototypes]
49 | void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:51:6: warning: no previous prototype for '__ubsan_handle_builtin_unreachable' [-Wmissing-prototypes]
51 | void __ubsan_handle_builtin_unreachable(void *_data) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/hyp/nvhe/ubsan.c:53:6: warning: no previous prototype for '__ubsan_handle_load_invalid_value' [-Wmissing-prototypes]
53 | void __ubsan_handle_load_invalid_value(void *_data, void *val) {}
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/kvm_ubsan_buffer +18 arch/arm64/kvm/hyp/nvhe/ubsan.c

> 9 #include <linux/percpu-defs.h>
10 #include <linux/kvm_host.h>
11 #include <asm/kvm_arm.h>
12 #include <asm/kvm_asm.h>
13 #include <asm/kvm_ubsan.h>
14 #include <asm/kvm_debug_buffer.h>
15 #include <kvm/arm_pmu.h>
16 #include <ubsan.h>
17
> 18 DEFINE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
19 kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
20

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (6.63 kB)
.config.gz (74.69 kB)
Download all attachments

2021-01-15 13:42:33

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 3/9] KVM: arm64: Enable UBSAN_BOUNDS for the both the kernel and hyp/nVHE

Hi Elena,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[cannot apply to kvmarm/next soc/for-next arm/for-next xlnx/master v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/c8a90dc1d55ba5e383a58cb48562cfdc803cb1b0
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
git checkout c8a90dc1d55ba5e383a58cb48562cfdc803cb1b0
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from arch/arm64/kvm/kvm_ubsan_buffer.c:12:
include/kvm/arm_pmu.h:52:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
52 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:54:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
54 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:56:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
56 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
>> arch/arm64/kvm/kvm_ubsan_buffer.c:20:6: warning: no previous prototype for '__kvm_check_ubsan_data' [-Wmissing-prototypes]
20 | void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
| ^~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c:30:6: warning: no previous prototype for 'iterate_kvm_ubsan_buffer' [-Wmissing-prototypes]
30 | void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c:43:6: warning: no previous prototype for '__kvm_check_ubsan_buffer' [-Wmissing-prototypes]
43 | void __kvm_check_ubsan_buffer(void)
| ^~~~~~~~~~~~~~~~~~~~~~~~


vim +/__kvm_check_ubsan_data +20 arch/arm64/kvm/kvm_ubsan_buffer.c

16
17 DECLARE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
18 kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
19
> 20 void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
21 {
22 switch (slot->type) {
23 case UBSAN_OUT_OF_BOUNDS:
24 __ubsan_handle_out_of_bounds(&slot->out_of_bounds_data,
25 slot->u_val.lval);
26 break;
27 }
28 }
29

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (3.57 kB)
.config.gz (74.69 kB)
Download all attachments

2021-01-15 14:34:13

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 9/9] KVM: arm64: Add UBSan tests for PKVM.

Hi Elena,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[cannot apply to kvmarm/next soc/for-next arm/for-next xlnx/master v5.11-rc3 next-20210115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/cd5e5083db55d9959f564a72bc348d83425a2838
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Elena-Petrova/UBSan-Enablement-for-hyp-nVHE-code/20210115-112509
git checkout cd5e5083db55d9959f564a72bc348d83425a2838
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from arch/arm64/kvm/kvm_ubsan_buffer.c:12:
include/kvm/arm_pmu.h:52:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
52 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:54:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
54 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
include/kvm/arm_pmu.h:56:15: warning: 'struct kvm_device_attr' declared inside parameter list will not be visible outside of this definition or declaration
56 | struct kvm_device_attr *attr);
| ^~~~~~~~~~~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c:19:6: warning: no previous prototype for '__kvm_check_ubsan_data' [-Wmissing-prototypes]
19 | void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
| ^~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c: In function '__kvm_check_ubsan_data':
>> arch/arm64/kvm/kvm_ubsan_buffer.c:21:2: warning: enumeration value 'UBSAN_NONE' not handled in switch [-Wswitch]
21 | switch (slot->type) {
| ^~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c: At top level:
arch/arm64/kvm/kvm_ubsan_buffer.c:62:6: warning: no previous prototype for 'iterate_kvm_ubsan_buffer' [-Wmissing-prototypes]
62 | void iterate_kvm_ubsan_buffer(unsigned long left, unsigned long right)
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/arm64/kvm/kvm_ubsan_buffer.c:75:6: warning: no previous prototype for '__kvm_check_ubsan_buffer' [-Wmissing-prototypes]
75 | void __kvm_check_ubsan_buffer(void)
| ^~~~~~~~~~~~~~~~~~~~~~~~
--
In file included from arch/arm64/kvm/hyp/nvhe/hyp-main.c:16:
arch/arm64/kvm/hyp/include/hyp/test_ubsan.h: In function 'test_ubsan_out_of_bounds':
>> arch/arm64/kvm/hyp/include/hyp/test_ubsan.h:55:15: warning: variable 'arr' set but not used [-Wunused-but-set-variable]
55 | volatile int arr[4];
| ^~~
arch/arm64/kvm/hyp/include/hyp/test_ubsan.h: In function 'test_ubsan_load_invalid_value':
>> arch/arm64/kvm/hyp/include/hyp/test_ubsan.h:63:19: warning: variable 'ptr' set but not used [-Wunused-but-set-variable]
63 | bool val, val2, *ptr;
| ^~~
arch/arm64/kvm/hyp/include/hyp/test_ubsan.h: In function 'test_ubsan_object_size_mismatch':
>> arch/arm64/kvm/hyp/include/hyp/test_ubsan.h:87:27: warning: variable 'val2' set but not used [-Wunused-but-set-variable]
87 | volatile long long *ptr, val2;
| ^~~~
arch/arm64/kvm/hyp/nvhe/hyp-main.c: At top level:
arch/arm64/kvm/hyp/nvhe/hyp-main.c:183:6: warning: no previous prototype for 'handle_trap' [-Wmissing-prototypes]
183 | void handle_trap(struct kvm_cpu_context *host_ctxt)
| ^~~~~~~~~~~


vim +/UBSAN_NONE +21 arch/arm64/kvm/kvm_ubsan_buffer.c

aba3219bbab3bb5c George Popescu 2021-01-14 15
aba3219bbab3bb5c George Popescu 2021-01-14 16 DECLARE_KVM_DEBUG_BUFFER(struct kvm_ubsan_info, kvm_ubsan_buffer,
aba3219bbab3bb5c George Popescu 2021-01-14 17 kvm_ubsan_buff_wr_ind, KVM_UBSAN_BUFFER_SIZE);
aba3219bbab3bb5c George Popescu 2021-01-14 18
c8a90dc1d55ba5e3 George Popescu 2021-01-14 19 void __kvm_check_ubsan_data(struct kvm_ubsan_info *slot)
c8a90dc1d55ba5e3 George Popescu 2021-01-14 20 {
c8a90dc1d55ba5e3 George Popescu 2021-01-14 @21 switch (slot->type) {
c8a90dc1d55ba5e3 George Popescu 2021-01-14 22 case UBSAN_OUT_OF_BOUNDS:
c8a90dc1d55ba5e3 George Popescu 2021-01-14 23 __ubsan_handle_out_of_bounds(&slot->out_of_bounds_data,
c8a90dc1d55ba5e3 George Popescu 2021-01-14 24 slot->u_val.lval);
c8a90dc1d55ba5e3 George Popescu 2021-01-14 25 break;
125f434abd282604 George Popescu 2021-01-14 26 case UBSAN_UNREACHABLE_DATA:
125f434abd282604 George Popescu 2021-01-14 27 __ubsan_handle_builtin_unreachable(&slot->unreachable_data);
125f434abd282604 George Popescu 2021-01-14 28 break;
3bd940afa9486b82 George Popescu 2021-01-14 29 case UBSAN_SHIFT_OUT_OF_BOUNDS:
3bd940afa9486b82 George Popescu 2021-01-14 30 __ubsan_handle_shift_out_of_bounds(&slot->shift_out_of_bounds_data,
3bd940afa9486b82 George Popescu 2021-01-14 31 slot->u_val.lval, slot->u_val.rval);
3bd940afa9486b82 George Popescu 2021-01-14 32 break;
3b42f0d25b7dd280 George Popescu 2021-01-14 33 case UBSAN_INVALID_DATA:
3b42f0d25b7dd280 George Popescu 2021-01-14 34 __ubsan_handle_load_invalid_value(&slot->invalid_value_data,
3b42f0d25b7dd280 George Popescu 2021-01-14 35 slot->u_val.lval);
3b42f0d25b7dd280 George Popescu 2021-01-14 36 break;
e7832e63ca596782 George Popescu 2021-01-14 37 case UBSAN_TYPE_MISMATCH:
e7832e63ca596782 George Popescu 2021-01-14 38 __ubsan_handle_type_mismatch(&slot->type_mismatch_data,
e7832e63ca596782 George Popescu 2021-01-14 39 slot->u_val.lval);
e7832e63ca596782 George Popescu 2021-01-14 40 break;
aaa9326468ea971e George Popescu 2021-01-14 41 case UBSAN_OVERFLOW_DATA:
aaa9326468ea971e George Popescu 2021-01-14 42 if (slot->u_val.op == '/') {
aaa9326468ea971e George Popescu 2021-01-14 43 __ubsan_handle_divrem_overflow(&slot->overflow_data,
aaa9326468ea971e George Popescu 2021-01-14 44 slot->u_val.lval, slot->u_val.rval);
aaa9326468ea971e George Popescu 2021-01-14 45 } else if (slot->u_val.op == '!') {
aaa9326468ea971e George Popescu 2021-01-14 46 __ubsan_handle_negate_overflow(&slot->overflow_data,
aaa9326468ea971e George Popescu 2021-01-14 47 slot->u_val.lval);
aaa9326468ea971e George Popescu 2021-01-14 48 } else if (slot->u_val.op == '+') {
aaa9326468ea971e George Popescu 2021-01-14 49 __ubsan_handle_add_overflow(&slot->overflow_data,
aaa9326468ea971e George Popescu 2021-01-14 50 slot->u_val.lval, slot->u_val.rval);
aaa9326468ea971e George Popescu 2021-01-14 51 } else if (slot->u_val.op == '-') {
aaa9326468ea971e George Popescu 2021-01-14 52 __ubsan_handle_sub_overflow(&slot->overflow_data,
aaa9326468ea971e George Popescu 2021-01-14 53 slot->u_val.lval, slot->u_val.rval);
aaa9326468ea971e George Popescu 2021-01-14 54 } else if (slot->u_val.op == '*') {
aaa9326468ea971e George Popescu 2021-01-14 55 __ubsan_handle_mul_overflow(&slot->overflow_data,
aaa9326468ea971e George Popescu 2021-01-14 56 slot->u_val.lval, slot->u_val.rval);
aaa9326468ea971e George Popescu 2021-01-14 57 }
aaa9326468ea971e George Popescu 2021-01-14 58 break;
c8a90dc1d55ba5e3 George Popescu 2021-01-14 59 }
c8a90dc1d55ba5e3 George Popescu 2021-01-14 60 }
aba3219bbab3bb5c George Popescu 2021-01-14 61

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (8.34 kB)
.config.gz (74.69 kB)
Download all attachments