i965: Don't write past the end of the application supplied buffer
authorIan Romanick <ian.d.romanick@intel.com>
Sat, 28 Feb 2015 02:43:00 +0000 (18:43 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 9 Mar 2015 21:07:14 +0000 (14:07 -0700)
Both the AMD and Intel APIs provide a dataSize parameter, and this
function would merrily ignore it.  Neither API specifies what to do when
the buffer isn't big enough.  I take the easy route of writing all the
complete bits of data that will fit.  With more complete specs, we could
probably do something different.

I noticed this while looking into an unused parameter warning.  The
warning was actually useful!

brw_performance_monitor.c: In function 'brw_get_perf_monitor_result':
brw_performance_monitor.c:1261:37: warning: unused parameter 'data_size' [-Wunused-parameter]
                             GLsizei data_size,
                                     ^

v2: Fix checks to include offset in the calculation.  Noticed by Jan.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jan Vesely <jan.vesely@rutgers.edu>
src/mesa/drivers/dri/i965/brw_performance_monitor.c

index 6c31d4c2e24fa908ce72ac6824c7a6cbeb3444da..2c8cd491a8e5a52ffa6740e5fae160361bd46feb 100644 (file)
@@ -1264,6 +1264,7 @@ brw_get_perf_monitor_result(struct gl_context *ctx,
 {
    struct brw_context *brw = brw_context(ctx);
    struct brw_perf_monitor_object *monitor = brw_perf_monitor(m);
+   const GLuint *const data_end = (GLuint *)((uint8_t *) data + data_size);
 
    DBG("GetResult(%d)\n", m->Name);
    brw_dump_perf_monitors(brw);
@@ -1309,9 +1310,11 @@ brw_get_perf_monitor_result(struct gl_context *ctx,
          if (counter < 0 || !BITSET_TEST(m->ActiveCounters[group], counter))
             continue;
 
-         data[offset++] = group;
-         data[offset++] = counter;
-         data[offset++] = monitor->oa_results[i];
+         if (data + offset + 3 <= data_end) {
+            data[offset++] = group;
+            data[offset++] = counter;
+            data[offset++] = monitor->oa_results[i];
+         }
       }
 
       clean_bookend_bo(brw);
@@ -1335,10 +1338,12 @@ brw_get_perf_monitor_result(struct gl_context *ctx,
 
       for (int i = 0; i < num_counters; i++) {
          if (BITSET_TEST(m->ActiveCounters[PIPELINE_STATS_COUNTERS], i)) {
-            data[offset++] = PIPELINE_STATS_COUNTERS;
-            data[offset++] = i;
-            *((uint64_t *) (&data[offset])) = monitor->pipeline_stats_results[i];
-            offset += 2;
+            if (data + offset + 4 <= data_end) {
+               data[offset++] = PIPELINE_STATS_COUNTERS;
+               data[offset++] = i;
+               *((uint64_t *) (&data[offset])) = monitor->pipeline_stats_results[i];
+               offset += 2;
+            }
          }
       }
    }