[PATCH v3 3/9] KVM: arm64: Enable UBSAN_BOUNDS for the both the kernel and hyp/nVHE
From: Elena Petrova <hidden>
Date: 2021-01-15 17:19:42
Also in:
kvmarm, lkml
Subsystem:
arm64 port (aarch64 architecture), kernel virtual machine for arm64 (kvm/arm64), the rest · Maintainers:
Catalin Marinas, Will Deacon, Marc Zyngier, Oliver Upton, Linus Torvalds
From: George Popescu <redacted> 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 <redacted> Signed-off-by: Elena Petrova <redacted> --- 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.296.g2bfb1c46d8-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel