From: George Popescu <georgepope@xxxxxxxxxx> Type mismatch undefined 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 instead of the value of the struct. 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 <georgepope@xxxxxxxxxx> --- 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 b643ac9a4090..a9f499f4ef6d 100644 --- a/arch/arm64/include/asm/kvm_ubsan.h +++ b/arch/arm64/include/asm/kvm_ubsan.h @@ -23,13 +23,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; @@ -41,3 +43,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 1888a1f51724..c99d919105aa 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 01bf2171af9e..21c242c92f0a 100644 --- a/arch/arm64/kvm/kvm_ubsan_buffer.c +++ b/arch/arm64/kvm/kvm_ubsan_buffer.c @@ -36,6 +36,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; } } @@ -51,4 +55,3 @@ void __kvm_check_ubsan_buffer(void) slot->type = 0; } } - -- 2.28.0.618.gf4bc123cb7-goog