i965: Pad buffer objects by 2kB in robust contexts to avoid OOB access.
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 3 Jun 2017 18:46:15 +0000 (11:46 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 14 Jul 2017 02:56:49 +0000 (19:56 -0700)
This is an annoyingly big hammer, but it seems less mean than disabling
UBO pushing, and I'm not sure what else to do.

Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/intel_buffer_objects.c

index a335c00afdebed329f2e9d794dd8578f4b99a7c9..e932badaafe4ccf27b078da25053af30e41a69ce 100644 (file)
@@ -74,8 +74,26 @@ static void
 alloc_buffer_object(struct brw_context *brw,
                     struct intel_buffer_object *intel_obj)
 {
-   intel_obj->buffer = brw_bo_alloc(brw->bufmgr, "bufferobj",
-                                         intel_obj->Base.Size, 64);
+   const struct gl_context *ctx = &brw->ctx;
+
+   uint64_t size = intel_obj->Base.Size;
+   if (ctx->Const.RobustAccess) {
+      /* Pad out buffer objects with an extra 2kB (half a page).
+       *
+       * When pushing UBOs, we need to safeguard against 3DSTATE_CONSTANT_*
+       * reading out of bounds memory.  The application might bind a UBO that's
+       * smaller than what the program expects.  Ideally, we'd bind an extra
+       * push buffer containing zeros, but we have a limited number of those,
+       * so it's not always viable.  Our only safe option is to pad all buffer
+       * objects by the maximum push data length, so that it will never read
+       * past the end of a BO.
+       *
+       * This is unfortunate, but it should result in at most 1 extra page,
+       * which probably isn't too terrible.
+       */
+      size += 64 * 32; /* max read length of 64 256-bit units */
+   }
+   intel_obj->buffer = brw_bo_alloc(brw->bufmgr, "bufferobj", size, 64);
 
    /* the buffer might be bound as a uniform buffer, need to update it
     */