From ea69f7bc89ce1f7b9d79a8b20cbb759e26bee749 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Wed, 20 Mar 2024 09:20:31 +0100 Subject: [PATCH] radv/rra: Detect BVHs with back edges Avoid overflowing the stack and fail validation. Reviewed-by: Friedrich Vock Part-of: --- src/amd/vulkan/radv_rra.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/amd/vulkan/radv_rra.c b/src/amd/vulkan/radv_rra.c index 2606a0fd060..ea2cbd8bb37 100644 --- a/src/amd/vulkan/radv_rra.c +++ b/src/amd/vulkan/radv_rra.c @@ -456,10 +456,15 @@ static const char *node_type_names[8] = { static bool rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void *node, uint32_t geometry_count, - uint32_t size, bool is_bottom_level) + uint32_t size, bool is_bottom_level, uint32_t depth) { struct rra_validation_context ctx = {0}; + if (depth > 1024) { + rra_validation_fail(&ctx, "depth > 1024"); + return true; + } + uint32_t cur_offset = (uint8_t *)node - data; snprintf(ctx.location, sizeof(ctx.location), "internal node (offset=%u)", cur_offset); @@ -486,7 +491,8 @@ rra_validate_node(struct hash_table_u64 *accel_struct_vas, uint8_t *data, void * snprintf(child_ctx.location, sizeof(child_ctx.location), "%s node (offset=%u)", node_type_names[type], offset); if (is_internal_node(type)) { - ctx.failed |= rra_validate_node(accel_struct_vas, data, data + offset, geometry_count, size, is_bottom_level); + ctx.failed |= + rra_validate_node(accel_struct_vas, data, data + offset, geometry_count, size, is_bottom_level, depth + 1); } else if (type == radv_bvh_node_instance) { struct radv_bvh_instance_node *src = (struct radv_bvh_instance_node *)(data + offset); uint64_t blas_va = node_to_addr(src->bvh_ptr) - src->bvh_offset; @@ -742,7 +748,7 @@ rra_dump_acceleration_structure(struct radv_rra_accel_struct_data *accel_struct, return VK_ERROR_VALIDATION_FAILED_EXT; } if (rra_validate_node(accel_struct_vas, data + header->bvh_offset, data + header->bvh_offset + src_root_offset, - header->geometry_count, accel_struct->size, !is_tlas)) { + header->geometry_count, accel_struct->size, !is_tlas, 0)) { return VK_ERROR_VALIDATION_FAILED_EXT; } }