[PATCH vkd3d 4/5] vkd3d: Validate src_box in ReadFromSubresource().

Józef Kucia joseph.kucia at gmail.com
Wed Aug 7 08:58:26 CDT 2019


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/resource.c | 40 +++++++++++++++++++++++++--
 tests/d3d12.c         | 63 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index cb2edd1439cf..463f373b9c61 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1041,6 +1041,33 @@ bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource)
     return resource->heap && is_cpu_accessible_heap(&resource->heap->desc.Properties);
 }
 
+static bool d3d12_resource_validate_box(const struct d3d12_resource *resource,
+        unsigned int sub_resource_idx, const D3D12_BOX *box)
+{
+    unsigned int mip_level = sub_resource_idx % resource->desc.MipLevels;
+    struct d3d12_device *device = resource->device;
+    const struct vkd3d_format *vkd3d_format;
+    uint32_t width_mask, height_mask;
+    uint64_t width, height, depth;
+
+    width = d3d12_resource_desc_get_width(&resource->desc, mip_level);
+    height = d3d12_resource_desc_get_height(&resource->desc, mip_level);
+    depth = d3d12_resource_desc_get_depth(&resource->desc, mip_level);
+
+    vkd3d_format = vkd3d_format_from_d3d12_resource_desc(device, &resource->desc, 0);
+    assert(vkd3d_format);
+    width_mask = vkd3d_format->block_width - 1;
+    height_mask = vkd3d_format->block_height - 1;
+
+    return box->left <= width && box->right <= width
+            && box->top <= height && box->bottom <= height
+            && box->front <= depth && box->back <= depth
+            && !(box->left & width_mask)
+            && !(box->right & width_mask)
+            && !(box->top & height_mask)
+            && !(box->bottom & height_mask);
+}
+
 /* ID3D12Resource */
 static inline struct d3d12_resource *impl_from_ID3D12Resource(ID3D12Resource *iface)
 {
@@ -1282,8 +1309,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
     HRESULT hr;
 
     TRACE("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, "
-            "src_sub_resource %u, src_box %p.\n",
-            iface, dst_data, dst_row_pitch, dst_slice_pitch, src_sub_resource, src_box);
+            "src_sub_resource %u, src_box %s.\n",
+            iface, dst_data, dst_row_pitch, dst_slice_pitch, src_sub_resource, debug_d3d12_box(src_box));
 
     if (d3d12_resource_is_buffer(resource))
     {
@@ -1311,6 +1338,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
 
     if (src_box)
     {
+        if (!d3d12_resource_validate_box(resource, src_sub_resource, src_box))
+        {
+            WARN("Invalid box %s.\n", debug_d3d12_box(src_box));
+            return E_INVALIDARG;
+        }
+
         box = *src_box;
     }
     else
@@ -1323,7 +1356,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
         box.back = d3d12_resource_desc_get_depth(&resource->desc, vk_sub_resource.mipLevel);
     }
     if (box.right <= box.left || box.bottom <= box.top || box.back <= box.front)
+    {
+        WARN("Empty box %s.\n", debug_d3d12_box(src_box));
         return S_OK;
+    }
 
     if (!d3d12_resource_is_cpu_accessible(resource))
     {
diff --git a/tests/d3d12.c b/tests/d3d12.c
index cc7113adfaff..39cbc9e6a87a 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -30465,6 +30465,19 @@ static void test_read_write_subresource(void)
         goto done;
     }
 
+    /* Invalid box */
+    set_box(&box, 0, 0, 0, 128, 100, 65);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    set_box(&box, 0, 0, 65, 128, 100, 65);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    set_box(&box, 128, 0, 0, 128, 100, 65);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
     /* NULL box */
     hr = ID3D12Resource_WriteToSubresource(src_texture, 0, NULL, dst_buffer, row_pitch, slice_pitch);
     todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
@@ -30474,6 +30487,10 @@ static void test_read_write_subresource(void)
     ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
 
     /* Empty box */
+    set_box(&box, 128, 100, 64, 128, 100, 64);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
     set_box(&box, 0, 0, 0, 0, 0, 0);
     hr = ID3D12Resource_WriteToSubresource(src_texture, 0, &box, dst_buffer, row_pitch, slice_pitch);
     todo ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
@@ -30625,7 +30642,51 @@ static void test_read_write_subresource(void)
 
     ID3D12Resource_Release(src_texture);
     ID3D12Resource_Release(dst_texture);
-    reset_command_list(command_list, context.allocator);
+
+    /* Invalid box */
+    resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+    resource_desc.Alignment = 0;
+    resource_desc.Width = 64;
+    resource_desc.Height = 32;
+    resource_desc.DepthOrArraySize = 1;
+    resource_desc.MipLevels = 1;
+    resource_desc.Format = DXGI_FORMAT_BC1_UNORM;
+    resource_desc.SampleDesc.Count = 1;
+    resource_desc.SampleDesc.Quality = 0;
+    resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+    resource_desc.Flags = 0;
+
+    memset(&heap_properties, 0, sizeof(heap_properties));
+    heap_properties.Type = D3D12_HEAP_TYPE_CUSTOM;
+    heap_properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
+    heap_properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
+    hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
+            &resource_desc, D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&src_texture);
+    ok(hr == S_OK, "Failed to create resource, hr %#x.\n", hr);
+
+    /* Unaligned coordinates for BC format */
+    set_box(&box, 0, 0, 0, 2, 2, 1);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    set_box(&box, 2, 2, 0, 4, 4, 1);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    set_box(&box, 2, 2, 0, 6, 6, 1);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    /* Invalid coordinates for resource dimensions */
+    set_box(&box, 0, 0, 0, 64, 32, 2);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    set_box(&box, 0, 0, 0, 68, 32, 1);
+    hr = ID3D12Resource_ReadFromSubresource(src_texture, dst_buffer, row_pitch, slice_pitch, 0, &box);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    ID3D12Resource_Release(src_texture);
 
 done:
     free(dst_buffer);
-- 
2.21.0




More information about the wine-devel mailing list