i965: Fix out-of-bounds access to brw_stage_state::surf_offset
authorDanylo Piliaiev <danylo.piliaiev@globallogic.com>
Fri, 27 Mar 2020 14:55:52 +0000 (16:55 +0200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 6 May 2020 16:09:20 +0000 (16:09 +0000)
../src/mesa/drivers/dri/i965/brw_wm_surface_state.c:1378:32: runtime error: index 3503345872 out of bounds for type 'uint32_t [149]'

brw_assign_common_binding_table_offsets has the following comment:
 "Unused groups are initialized to 0xd0d0d0d0 to make it obvious that they're
 unused but also make sure that addition of small offsets to them will
 trigger some of our asserts that surface indices are < BRW_MAX_SURFACES."

Cc: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4350>

src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index f51789799e7f66e29d5618ec7c5bf846158ce22f..ae4cdedd5601c461594ad3c9178128ba1cf32313 100644 (file)
@@ -1362,33 +1362,39 @@ brw_upload_ubo_surfaces(struct brw_context *brw, struct gl_program *prog,
                  prog->info.num_abos == 0))
       return;
 
-   uint32_t *ubo_surf_offsets =
-      &stage_state->surf_offset[prog_data->binding_table.ubo_start];
-
-   for (int i = 0; i < prog->info.num_ubos; i++) {
-      struct gl_buffer_binding *binding =
-         &ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding];
-      upload_buffer_surface(brw, binding, &ubo_surf_offsets[i],
-                            ISL_FORMAT_R32G32B32A32_FLOAT, 0);
+   if (prog->info.num_ubos) {
+      assert(prog_data->binding_table.ubo_start < BRW_MAX_SURFACES);
+      uint32_t *ubo_surf_offsets =
+         &stage_state->surf_offset[prog_data->binding_table.ubo_start];
+
+      for (int i = 0; i < prog->info.num_ubos; i++) {
+         struct gl_buffer_binding *binding =
+            &ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding];
+         upload_buffer_surface(brw, binding, &ubo_surf_offsets[i],
+                               ISL_FORMAT_R32G32B32A32_FLOAT, 0);
+      }
    }
 
-   uint32_t *ssbo_surf_offsets =
-      &stage_state->surf_offset[prog_data->binding_table.ssbo_start];
-   uint32_t *abo_surf_offsets = ssbo_surf_offsets + prog->info.num_ssbos;
-
-   for (int i = 0; i < prog->info.num_abos; i++) {
-      struct gl_buffer_binding *binding =
-         &ctx->AtomicBufferBindings[prog->sh.AtomicBuffers[i]->Binding];
-      upload_buffer_surface(brw, binding, &abo_surf_offsets[i],
-                            ISL_FORMAT_RAW, RELOC_WRITE);
-   }
+   if (prog->info.num_ssbos || prog->info.num_abos) {
+      assert(prog_data->binding_table.ssbo_start < BRW_MAX_SURFACES);
+      uint32_t *ssbo_surf_offsets =
+         &stage_state->surf_offset[prog_data->binding_table.ssbo_start];
+      uint32_t *abo_surf_offsets = ssbo_surf_offsets + prog->info.num_ssbos;
+
+      for (int i = 0; i < prog->info.num_abos; i++) {
+         struct gl_buffer_binding *binding =
+            &ctx->AtomicBufferBindings[prog->sh.AtomicBuffers[i]->Binding];
+         upload_buffer_surface(brw, binding, &abo_surf_offsets[i],
+                               ISL_FORMAT_RAW, RELOC_WRITE);
+      }
 
-   for (int i = 0; i < prog->info.num_ssbos; i++) {
-      struct gl_buffer_binding *binding =
-         &ctx->ShaderStorageBufferBindings[prog->sh.ShaderStorageBlocks[i]->Binding];
+      for (int i = 0; i < prog->info.num_ssbos; i++) {
+         struct gl_buffer_binding *binding =
+            &ctx->ShaderStorageBufferBindings[prog->sh.ShaderStorageBlocks[i]->Binding];
 
-      upload_buffer_surface(brw, binding, &ssbo_surf_offsets[i],
-                            ISL_FORMAT_RAW, RELOC_WRITE);
+         upload_buffer_surface(brw, binding, &ssbo_surf_offsets[i],
+                               ISL_FORMAT_RAW, RELOC_WRITE);
+      }
    }
 
    stage_state->push_constants_dirty = true;