From e23ddd6cd1bbe04c19a4c58467644b09c2ff6ce7 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Mon, 9 Dec 2024 16:30:55 +0100 Subject: [PATCH] adding securities --- Includes/Pulse.h | 1 + Sources/PulseBackend.c | 1 + Sources/PulseBuffer.c | 26 ++++++++++++++++++++++++-- Sources/PulseDevice.c | 10 ++++++++++ Sources/PulseImage.c | 25 +++++++++++++++++++++++-- Sources/PulseInternal.h | 8 ++++++++ Tests/Vulkan/Buffer.c | 30 ++++++++++++++++++++++++++++++ Tests/Vulkan/Common.c | 2 ++ Tests/Vulkan/Common.h | 4 ++++ 9 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Includes/Pulse.h b/Includes/Pulse.h index d701b00..275f31f 100644 --- a/Includes/Pulse.h +++ b/Includes/Pulse.h @@ -107,6 +107,7 @@ typedef enum PulseErrorType PULSE_ERROR_DEVICE_LOST, PULSE_ERROR_INVALID_INTERNAL_POINTER, PULSE_ERROR_MAP_FAILED, + PULSE_ERROR_INVALID_DEVICE, } PulseErrorType; typedef enum PulseImageType diff --git a/Sources/PulseBackend.c b/Sources/PulseBackend.c index 56a16c2..1b16caf 100644 --- a/Sources/PulseBackend.c +++ b/Sources/PulseBackend.c @@ -164,6 +164,7 @@ PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error) case PULSE_ERROR_DEVICE_LOST: return "device has been lost"; case PULSE_ERROR_INVALID_INTERNAL_POINTER: return "invalid internal pointer"; case PULSE_ERROR_MAP_FAILED: return "memory mapping failed"; + case PULSE_ERROR_INVALID_DEVICE: return "device is invalid"; default: return "invalid error type"; }; diff --git a/Sources/PulseBuffer.c b/Sources/PulseBuffer.c index 9bee98b..3e70ad2 100644 --- a/Sources/PulseBuffer.c +++ b/Sources/PulseBuffer.c @@ -5,6 +5,7 @@ #include "Pulse.h" #include "PulseDefs.h" #include "PulseInternal.h" +#include "PulseProfile.h" PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos) { @@ -18,7 +19,13 @@ PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCre return PULSE_NULL_HANDLE; } } - return device->PFN_CreateBuffer(device, create_infos); + PulseBuffer buffer = device->PFN_CreateBuffer(device, create_infos); + if(buffer == PULSE_NULL_HANDLE) + return PULSE_NULL_HANDLE; + PULSE_EXPAND_ARRAY_IF_NEEDED(device->allocated_buffers, PulseBuffer, device->allocated_buffers_size, device->allocated_buffers_capacity, 64); + device->allocated_buffers[device->allocated_buffers_size] = buffer; + device->allocated_buffers_size++; + return buffer; } PULSE_API bool PulseMapBuffer(PulseBuffer buffer, void** data) @@ -53,5 +60,20 @@ PULSE_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer) if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) PulseLogWarning(device->backend, "buffer is still mapped, consider unmapping it before destroy"); } - return device->PFN_DestroyBuffer(device, buffer); + if(buffer->device != device) + { + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + PulseLogErrorFmt(device->backend, "cannot destroy buffer [%p] that have been allocated with device [%p] using device [%p]", buffer, buffer->device, device); + PulseSetInternalError(PULSE_ERROR_INVALID_DEVICE); + return; + } + for(uint32_t i = 0; i < device->allocated_buffers_size; i++) + { + if(device->allocated_buffers[i] == buffer) + { + PULSE_DEFRAG_ARRAY(device->allocated_buffers, device->allocated_buffers_size, i); + break; + } + } + device->PFN_DestroyBuffer(device, buffer); } diff --git a/Sources/PulseDevice.c b/Sources/PulseDevice.c index 4488c42..30c1526 100644 --- a/Sources/PulseDevice.c +++ b/Sources/PulseDevice.c @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in LICENSE #include +#include "PulseDefs.h" #include "PulseInternal.h" PULSE_API PulseDevice PulseCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count) @@ -14,6 +15,15 @@ PULSE_API PulseDevice PulseCreateDevice(PulseBackend backend, PulseDevice* forbi PULSE_API void PulseDestroyDevice(PulseDevice device) { PULSE_CHECK_HANDLE(device); + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + { + if(device->allocated_buffers_size != 0) + PulseLogErrorFmt(device->backend, "some buffers allocated using device [%p] were not freed (%d active allocations)", device, device->allocated_buffers_size); + if(device->allocated_images_size != 0) + PulseLogErrorFmt(device->backend, "some images allocated using device [%p] were not freed (%d active allocations)", device, device->allocated_images_size); + } + free(device->allocated_buffers); + free(device->allocated_images); device->PFN_DestroyDevice(device); device->driver_data = PULSE_NULLPTR; } diff --git a/Sources/PulseImage.c b/Sources/PulseImage.c index cdd1ffd..e0210c7 100644 --- a/Sources/PulseImage.c +++ b/Sources/PulseImage.c @@ -99,7 +99,13 @@ PULSE_API PulseImage PulseCreateImage(PulseDevice device, const PulseImageCreate if(failed) return PULSE_NULL_HANDLE; } - return device->PFN_CreateImage(device, create_infos); + PulseImage image = device->PFN_CreateImage(device, create_infos); + if(image == PULSE_NULL_HANDLE) + return PULSE_NULL_HANDLE; + PULSE_EXPAND_ARRAY_IF_NEEDED(device->allocated_images, PulseImage, device->allocated_images_size, device->allocated_images_capacity, 64); + device->allocated_images[device->allocated_images_size] = image; + device->allocated_images_size++; + return image; } PULSE_API bool PulseIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage) @@ -118,5 +124,20 @@ PULSE_API void PulseDestroyImage(PulseDevice device, PulseImage image) PulseLogWarning(device->backend, "image is NULL, this may be a bug in your application"); return; } - return device->PFN_DestroyImage(device, image); + if(image->device != device) + { + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + PulseLogErrorFmt(device->backend, "cannot destroy image [%p] that have been allocated with device [%p] using device [%p]", image, image->device, device); + PulseSetInternalError(PULSE_ERROR_INVALID_DEVICE); + return; + } + for(uint32_t i = 0; i < device->allocated_images_size; i++) + { + if(device->allocated_images[i] == image) + { + PULSE_DEFRAG_ARRAY(device->allocated_images, device->allocated_images_size, i); + break; + } + } + device->PFN_DestroyImage(device, image); } diff --git a/Sources/PulseInternal.h b/Sources/PulseInternal.h index db8629f..15606b3 100644 --- a/Sources/PulseInternal.h +++ b/Sources/PulseInternal.h @@ -81,6 +81,14 @@ typedef struct PulseDeviceHandler // Attributes void* driver_data; PulseBackend backend; + + PulseBuffer* allocated_buffers; + uint32_t allocated_buffers_size; + uint32_t allocated_buffers_capacity; + + PulseImage* allocated_images; + uint32_t allocated_images_size; + uint32_t allocated_images_capacity; } PulseDeviceHandler; typedef struct PulseFenceHandler diff --git a/Tests/Vulkan/Buffer.c b/Tests/Vulkan/Buffer.c index 593fb52..79fa3ae 100644 --- a/Tests/Vulkan/Buffer.c +++ b/Tests/Vulkan/Buffer.c @@ -112,8 +112,38 @@ void TestBufferMapping() CleanupPulse(backend); } +void TestBufferDestruction() +{ + PulseBackend backend; + SetupPulse(&backend); + PulseDevice device; + SetupDevice(backend, &device); + + PulseDevice other_device; + SetupDevice(backend, &other_device); + + { + PulseBufferCreateInfo buffer_create_info = { 0 }; + buffer_create_info.size = 256; + buffer_create_info.usage = PULSE_BUFFER_USAGE_STORAGE_READ; + PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info); + TEST_ASSERT_NOT_EQUAL_MESSAGE(buffer, PULSE_NULL_HANDLE, PulseVerbaliseErrorType(PulseGetLastErrorType())); + + DISABLE_ERRORS; + RESET_ERRORS_CHECK; + PulseDestroyBuffer(other_device, buffer); + TEST_ASSERT_TRUE(HAS_RECIEVED_ERROR); + ENABLE_ERRORS; + } + + CleanupDevice(device); + CleanupDevice(other_device); + CleanupPulse(backend); +} + void TestBuffer() { RUN_TEST(TestBufferCreation); RUN_TEST(TestBufferMapping); + RUN_TEST(TestBufferDestruction); } diff --git a/Tests/Vulkan/Common.c b/Tests/Vulkan/Common.c index 2fa674e..378389a 100644 --- a/Tests/Vulkan/Common.c +++ b/Tests/Vulkan/Common.c @@ -2,11 +2,13 @@ #include bool errors_enabled = true; +bool has_recieved_error = false; void DebugCallBack(PulseDebugMessageSeverity severity, const char* message) { if(errors_enabled && severity == PULSE_DEBUG_MESSAGE_SEVERITY_ERROR) TEST_FAIL_MESSAGE(message); + has_recieved_error = true; } #define LOG_MESSAGE_MAX_LENGTH 4096 diff --git a/Tests/Vulkan/Common.h b/Tests/Vulkan/Common.h index e11c3e5..c8773e2 100644 --- a/Tests/Vulkan/Common.h +++ b/Tests/Vulkan/Common.h @@ -23,6 +23,10 @@ extern bool errors_enabled; #define DISABLE_ERRORS errors_enabled = false #define ENABLE_ERRORS errors_enabled = true +extern bool has_recieved_error; +#define RESET_ERRORS_CHECK has_recieved_error = false +#define HAS_RECIEVED_ERROR ((bool)(has_recieved_error == true)) + void DebugCallBack(PulseDebugMessageSeverity severity, const char* message); void SetupPulse(PulseBackend* backend); void SetupDevice(PulseBackend backend, PulseDevice* device);