Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- configure.ac | 1 + include/private/vkd3d_common.h | 11 +++++++++++ libs/vkd3d/command.c | 4 ++-- libs/vkd3d/device.c | 5 ++--- 4 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac index 275bca26..88d58e40 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,7 @@ AS_IF([test "x$with_xcb" != "xno"], dnl Check for functions VKD3D_CHECK_FUNC([HAVE_BUILTIN_CLZ], [__builtin_clz], [__builtin_clz(0)]) VKD3D_CHECK_FUNC([HAVE_BUILTIN_POPCOUNT], [__builtin_popcount], [__builtin_popcount(0)]) +VKD3D_CHECK_FUNC([HAVE_BUILTIN_ADD_OVERFLOW], [__builtin_add_overflow], [__builtin_add_overflow(0, 0, (int *)0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_ADD_AND_FETCH], [__sync_add_and_fetch], [__sync_add_and_fetch((int *)0, 0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_SUB_AND_FETCH], [__sync_sub_and_fetch], [__sync_sub_and_fetch((int *)0, 0)])
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 4ce2a2e3..8e729177 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -138,6 +138,17 @@ static inline void *vkd3d_memmem( const void *haystack, size_t haystack_len, con return NULL; }
+static inline bool vkd3d_bound_range(uint64_t start, uint64_t count, uint64_t limit) +{ +#ifdef HAVE_BUILTIN_ADD_OVERFLOW + uint64_t sum; + + return !__builtin_add_overflow(start, count, &sum) && sum <= limit; +#else + return start <= limit && count <= limit - start; +#endif +} + static inline int ascii_isupper(int c) { return 'A' <= c && c <= 'Z'; diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 116a8a62..60c4b37c 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -4421,7 +4421,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi null_resources = &list->device->null_resources; gpu_va_allocator = &list->device->gpu_va_allocator;
- if (start_slot >= ARRAY_SIZE(list->strides) || view_count > ARRAY_SIZE(list->strides) - start_slot) + if (!vkd3d_bound_range(start_slot, view_count, ARRAY_SIZE(list->strides))) { WARN("Invalid start slot %u / view count %u.\n", start_slot, view_count); return; @@ -4476,7 +4476,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm return; }
- if (start_slot >= ARRAY_SIZE(buffers) || view_count > ARRAY_SIZE(buffers) - start_slot) + if (!vkd3d_bound_range(start_slot, view_count, ARRAY_SIZE(buffers))) { WARN("Invalid start slot %u / view count %u.\n", start_slot, view_count); return; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 159bc470..ac6f14c7 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1925,7 +1925,7 @@ static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct base = allocator->fallback_floor; ceiling = ~(D3D12_GPU_VIRTUAL_ADDRESS)0; ceiling -= alignment - 1; - if (aligned_size > ceiling || ceiling - aligned_size < base) + if (!vkd3d_bound_range(base, aligned_size, ceiling)) return 0;
base = (base + (alignment - 1)) & ~((D3D12_GPU_VIRTUAL_ADDRESS)alignment - 1); @@ -3515,8 +3515,7 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *i
array_size = d3d12_resource_desc_get_layer_count(desc);
- if (first_sub_resource >= desc->MipLevels * array_size - || sub_resource_count > desc->MipLevels * array_size - first_sub_resource) + if (!vkd3d_bound_range(first_sub_resource, sub_resource_count, desc->MipLevels * array_size)) { WARN("Invalid sub-resource range %u-%u for resource.\n", first_sub_resource, sub_resource_count); return;