From 3d804851befa0cbea7f663d597308012df115461 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 29 Nov 2024 09:24:13 +0100 Subject: [PATCH] radv: try to detect use-after-free with address binding report This performs some very basic verifications with the faulty VA we get from the kernel. This will probably be improved over time. Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_debug.c | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/amd/vulkan/radv_debug.c b/src/amd/vulkan/radv_debug.c index 693e033a63a..988b2548218 100644 --- a/src/amd/vulkan/radv_debug.c +++ b/src/amd/vulkan/radv_debug.c @@ -60,6 +60,46 @@ radv_dump_address_binding_reports(struct radv_device *device, FILE *f) simple_mtx_unlock(&tracker->mtx); } +static void +radv_dump_address_binding_report_check(struct radv_device *device, uint64_t va, FILE *f) +{ + struct radv_address_binding_tracker *tracker = device->addr_binding_tracker; + bool va_found = false; + bool va_valid = false; + + if (!tracker) + return; + + fprintf(f, "\nPerforming some verifications with address binding report...\n"); + + simple_mtx_lock(&tracker->mtx); + + util_dynarray_foreach (&tracker->reports, struct radv_address_binding_report, report) { + if (va < report->va || va >= report->va + report->size) + continue; + + if (report->object_type == VK_OBJECT_TYPE_DEVICE_MEMORY) { + if (report->binding_type == VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT) { + va_valid = true; /* BO alloc */ + } else { + va_valid = false; /* BO destroy */ + } + } + + radv_dump_address_binding_report(report, f); + va_found = true; + } + + simple_mtx_unlock(&tracker->mtx); + + if (va_found) { + if (!va_valid) + fprintf(f, "\nPotential use-after-free detected! See addr_binding_report.log for more info.\n"); + } else { + fprintf(f, "VA not found!\n"); + } +} + static VkBool32 VKAPI_PTR radv_address_binding_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_types, @@ -803,6 +843,8 @@ radv_dump_vm_fault(struct radv_device *device, const struct radv_winsys_gpuvm_fa fprintf(f, "VM fault report.\n\n"); fprintf(f, "Failing VM page: 0x%08" PRIx64 "\n", fault_info->addr); ac_print_gpuvm_fault_status(f, pdev->info.gfx_level, fault_info->status); + + radv_dump_address_binding_report_check(device, fault_info->addr, f); } static bool