From e8547392b029959e4f76b1e4ad9d4fe71255bd72 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Sat, 15 Oct 2022 11:52:41 +0200 Subject: [PATCH] radv/rra: Add basic header validation Reviewed-by: Friedrich Vock Part-of: --- src/amd/vulkan/radv_rra.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/amd/vulkan/radv_rra.c b/src/amd/vulkan/radv_rra.c index d25c5cb330f..b1b7b6a6efb 100644 --- a/src/amd/vulkan/radv_rra.c +++ b/src/amd/vulkan/radv_rra.c @@ -403,7 +403,7 @@ rra_parent_table_index_from_offset(uint32_t offset, uint32_t parent_table_size) static void PRINTFLIKE(2, 3) rra_accel_struct_validation_fail(uint32_t offset, const char *reason, ...) { - fprintf(stderr, "radv: AS validation failed at node with offset 0x%x with reason: ", offset); + fprintf(stderr, "radv: AS validation failed at offset 0x%x with reason: ", offset); va_list list; va_start(list, reason); @@ -413,6 +413,25 @@ rra_accel_struct_validation_fail(uint32_t offset, const char *reason, ...) fprintf(stderr, "\n"); } +static bool +rra_validate_header(struct radv_acceleration_structure *accel_struct, + const struct radv_accel_struct_header *header) +{ + bool result = true; + + if (header->bvh_offset >= accel_struct->size) { + rra_accel_struct_validation_fail(0, "Invalid BVH offset %u", header->bvh_offset); + result = false; + } + + if (header->instance_count * sizeof(struct radv_bvh_instance_node) >= accel_struct->size) { + rra_accel_struct_validation_fail(0, "Too many instances"); + result = false; + } + + return result; +} + static bool is_internal_node(uint32_t type) { @@ -696,12 +715,16 @@ rra_dump_acceleration_structure(struct rra_copied_accel_struct *copied_struct, /* convert root node id to offset */ uint32_t src_root_offset = (RADV_BVH_ROOT_NODE & ~7) << 3; - if (should_validate) + if (should_validate) { + if (!rra_validate_header(accel_struct, header)) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } if (!rra_validate_node(accel_struct_vas, data + header->bvh_offset, data + header->bvh_offset + src_root_offset, src_root_offset, accel_struct->size, !is_tlas)) { return VK_ERROR_VALIDATION_FAILED_EXT; } + } struct rra_bvh_info bvh_info = {0}; rra_gather_bvh_info(data + header->bvh_offset, RADV_BVH_ROOT_NODE, &bvh_info);