winsys/virgl: correct resource and handle allocation (v2)
authorGert Wollny <gert.wollny@collabora.com>
Mon, 3 Sep 2018 08:05:44 +0000 (10:05 +0200)
committerGert Wollny <gw.fossdev@gmail.com>
Wed, 5 Sep 2018 11:54:01 +0000 (13:54 +0200)
Fixes crash with
  piglit/bin/map_buffer_range-invalidate CopyBufferSubData \
                               increment-offset -auto -fbo

* Resize the resource storage already when the count is equal to the
  allocated size, fixes:

  Invalid write of size 8
  at 0xB72E4CF: virgl_drm_add_res (virgl_drm_winsys.c:629)
  by 0xB72E4CF: virgl_drm_emit_res (virgl_drm_winsys.c:663)
  by 0xB72A44A: virgl_encode_resource_copy_region (virgl_encode.c:776)
  by 0xB40CD12: st_copy_buffer_subdata (st_cb_bufferobjects.c:585)
  by 0xB244A3B: _mesa_CopyBufferSubData (bufferobj.c:2940)
  by 0x109A1E: upload (invalidate.c:169)
  by 0x109C2F: piglit_display (invalidate.c:215)
  by 0x4F80FBE: run_test (piglit_fbo_framework.c:52)
  by 0x4F66E5F: piglit_gl_test_run (piglit-framework-gl.c:229)
  by 0x10949D: main (invalidate.c:47)
  Address 0xbe07d30 is 0 bytes after a block of size 4,096 alloc'd
  at 0x4C31B25: calloc (in
       /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  by 0xB72DAAF: virgl_drm_cmd_buf_create (virgl_drm_winsys.c:567)

* Also resize the space allocated for the handles, fixes:

  Invalid write of size 4
  at 0xB72E4F0: virgl_drm_add_res (virgl_drm_winsys.c:631)
  by 0xB72E4F0: virgl_drm_emit_res (virgl_drm_winsys.c:663)
  by 0xB72A44A: virgl_encode_resource_copy_region (virgl_encode.c:776)
  by 0xB40CD12: st_copy_buffer_subdata (st_cb_bufferobjects.c:585)
  by 0xB244A3B: _mesa_CopyBufferSubData (bufferobj.c:2940)
  by 0x109A1E: upload (invalidate.c:169)
  by 0x109C2F: piglit_display (invalidate.c:215)
  by 0x4F80FBE: run_test (piglit_fbo_framework.c:52)
  by 0x4F66E5F: piglit_gl_test_run (piglit-framework-gl.c:229)
  by 0x10949D: main (invalidate.c:47)
  Address 0xbe08570 is 0 bytes after a block of size 2,048 alloc'd
  at 0x4C2FB0F: malloc (
    in /usr/lib/valgrind/vgpreload_memcheck-amd64- linux.so)
  by 0xB72DAC8: virgl_drm_cmd_buf_create (virgl_drm_winsys.c:572)

Fixes: 4b15b5e803e ("virgl: resize resource bo allocation if we need to.")
v2: - Use REALLOC macro and avoid memory leak when re-allocation fails
    - add Fixes tag (both Emil Velikov)
    - reorder commit message

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c

index aad6430c417dd9ba94751f6b8d34d6c28879992e..80c93be70c91428c37f2550648ed9b9d0d2c6b07 100644 (file)
@@ -617,13 +617,26 @@ static void virgl_drm_add_res(struct virgl_drm_winsys *qdws,
 {
    unsigned hash = res->res_handle & (sizeof(cbuf->is_handle_added)-1);
 
-   if (cbuf->cres > cbuf->nres) {
-      cbuf->nres += 256;
-      cbuf->res_bo = realloc(cbuf->res_bo, cbuf->nres * sizeof(struct virgl_hw_buf*));
-      if (!cbuf->res_bo) {
-          fprintf(stderr,"failure to add relocation %d, %d\n", cbuf->cres, cbuf->nres);
+   if (cbuf->cres >= cbuf->nres) {
+      unsigned new_nres = cbuf->nres + 256;
+      void *new_ptr = REALLOC(cbuf->res_bo,
+                              cbuf->nres * sizeof(struct virgl_hw_buf*),
+                              new_nres * sizeof(struct virgl_hw_buf*));
+      if (!new_ptr) {
+          fprintf(stderr,"failure to add relocation %d, %d\n", cbuf->cres, new_nres);
           return;
       }
+      cbuf->res_bo = new_ptr;
+
+      new_ptr = REALLOC(cbuf->res_hlist,
+                        cbuf->nres * sizeof(uint32_t),
+                        new_nres * sizeof(uint32_t));
+      if (!new_ptr) {
+          fprintf(stderr,"failure to add hlist relocation %d, %d\n", cbuf->cres, cbuf->nres);
+          return;
+      }
+      cbuf->res_hlist = new_ptr;
+      cbuf->nres = new_nres;
    }
 
    cbuf->res_bo[cbuf->cres] = NULL;