pvr: Fix possible seg fault on csb copy.
authorKarmjit Mahil <Karmjit.Mahil@imgtec.com>
Fri, 14 Oct 2022 12:09:41 +0000 (13:09 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 19 Oct 2022 15:24:53 +0000 (15:24 +0000)
When copying the secondary command buffer's deferred control stream
to the main stream we have to first allocate space in the main
stream. In case the allocation failed we were attempting to
memcpy() to a NULL destination causing a NULL dereference.

This fixes CID 1515977.

Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19136>

src/imagination/vulkan/pvr_cmd_buffer.c
src/imagination/vulkan/pvr_csb.c
src/imagination/vulkan/pvr_csb.h

index ad71ad3..8c2ea2f 100644 (file)
@@ -5831,8 +5831,12 @@ pvr_execute_graphics_cmd_buffer(struct pvr_cmd_buffer *cmd_buffer,
          if (result != VK_SUCCESS)
             return;
 
-         pvr_csb_copy(&primary_sub_cmd->gfx.control_stream,
-                      &sec_sub_cmd->gfx.control_stream);
+         result = pvr_csb_copy(&primary_sub_cmd->gfx.control_stream,
+                               &sec_sub_cmd->gfx.control_stream);
+         if (result != VK_SUCCESS) {
+            cmd_buffer->state.status = result;
+            return;
+         }
       } else {
          result = pvr_execute_deferred_cmd_buffer(cmd_buffer, sec_cmd_buffer);
          if (result != VK_SUCCESS)
index 51d25d4..0b5c63e 100644 (file)
@@ -241,7 +241,7 @@ void *pvr_csb_alloc_dwords(struct pvr_csb *csb, uint32_t num_dwords)
  * \param[in,out] csb_dst Destination control Stream Builder object.
  * \param[in]     csb_src Source Control Stream Builder object.
  */
-void pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src)
+VkResult pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src)
 {
    const uint8_t stream_link_space = (pvr_cmd_length(VDMCTRL_STREAM_LINK0) +
                                       pvr_cmd_length(VDMCTRL_STREAM_LINK1)) *
@@ -249,6 +249,7 @@ void pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src)
    const uint32_t size =
       util_dynarray_num_elements(&csb_src->deferred_cs_mem, char);
    const uint8_t *start = util_dynarray_begin(&csb_src->deferred_cs_mem);
+   void *destination;
 
    /* Only deferred control stream supported as src. */
    assert(csb_src->stream_type == PVR_CMD_STREAM_TYPE_GRAPHICS_DEFERRED);
@@ -266,7 +267,15 @@ void pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src)
 
    assert(size < (PVR_CMD_BUFFER_CSB_BO_SIZE - stream_link_space));
 
-   memcpy(pvr_csb_alloc_dwords(csb_dst, size), start, size);
+   destination = pvr_csb_alloc_dwords(csb_dst, size);
+   if (!destination) {
+      assert(csb_dst->status != VK_SUCCESS);
+      return csb_dst->status;
+   }
+
+   memcpy(destination, start, size);
+
+   return VK_SUCCESS;
 }
 
 /**
index dd3cb74..7a739eb 100644 (file)
@@ -127,7 +127,7 @@ void pvr_csb_init(struct pvr_device *device,
                   struct pvr_csb *csb);
 void pvr_csb_finish(struct pvr_csb *csb);
 void *pvr_csb_alloc_dwords(struct pvr_csb *csb, uint32_t num_dwords);
-void pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src);
+VkResult pvr_csb_copy(struct pvr_csb *csb_dst, struct pvr_csb *csb_src);
 void pvr_csb_emit_link(struct pvr_csb *csb, pvr_dev_addr_t addr, bool ret);
 VkResult pvr_csb_emit_return(struct pvr_csb *csb);
 VkResult pvr_csb_emit_terminate(struct pvr_csb *csb);