From e33447aac62da5e7fe8f6a262cacaa97ce212ef5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 31 Oct 2011 19:26:53 +0000 Subject: [PATCH] svga: Fix potential buffer overflow in rs draw state. Reviewed-by: Brian Paul --- src/gallium/drivers/svga/svga_context.h | 12 +++++------- src/gallium/drivers/svga/svga_state_constants.c | 12 ++++++------ src/gallium/drivers/svga/svga_state_rss.c | 3 +++ src/gallium/drivers/svga/svga_state_tss.c | 5 +++++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 07d3c5f2c25..47e08ba68e1 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -36,6 +36,8 @@ #include "tgsi/tgsi_scan.h" #include "svga_state.h" +#include "svga_hw_reg.h" +#include "svga3d_shaderdefs.h" #define SVGA_TEX_UNITS 8 @@ -236,10 +238,6 @@ struct svga_state float zero_stride_constants[PIPE_MAX_ATTRIBS*4]; }; -#define RS_MAX 97 -#define TS_MAX 30 -#define CB_MAX 256 - struct svga_prescale { float translate[4]; float scale[4]; @@ -276,9 +274,9 @@ struct svga_hw_view_state */ struct svga_hw_draw_state { - unsigned rs[RS_MAX]; - unsigned ts[16][TS_MAX]; - float cb[PIPE_SHADER_TYPES][CB_MAX][4]; + unsigned rs[SVGA3D_RS_MAX]; + unsigned ts[SVGA3D_PIXEL_SAMPLERREG_MAX][SVGA3D_TS_MAX]; + float cb[PIPE_SHADER_TYPES][SVGA3D_CONSTREG_MAX][4]; struct svga_shader_result *fs; struct svga_shader_result *vs; diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index a1c5ee84f63..245b6d4b96c 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -68,10 +68,10 @@ emit_const(struct svga_context *svga, unsigned shader, unsigned i, { enum pipe_error ret = PIPE_OK; - assert(i < CB_MAX); - assert(shader < PIPE_SHADER_TYPES); + assert(i < SVGA3D_CONSTREG_MAX); + if (memcmp(svga->state.hw_draw.cb[shader][i], value, 4 * sizeof(float)) != 0) { if (SVGA_DEBUG & DEBUG_CONSTS) debug_printf("%s %s %u: %f %f %f %f\n", @@ -112,13 +112,13 @@ static enum pipe_error emit_const_range( struct svga_context *svga, enum pipe_error ret; #ifdef DEBUG - if (offset + count > CB_MAX) { + if (offset + count > SVGA3D_CONSTREG_MAX) { debug_printf("svga: too many constants (offset + count = %u)\n", offset + count); } #endif - if (offset > CB_MAX) { + if (offset > SVGA3D_CONSTREG_MAX) { /* This isn't OK, but if we propagate an error all the way up we'll * just get into more trouble. * XXX note that offset is always zero at this time so this is moot. @@ -126,13 +126,13 @@ static enum pipe_error emit_const_range( struct svga_context *svga, return PIPE_OK; } - if (offset + count > CB_MAX) { + if (offset + count > SVGA3D_CONSTREG_MAX) { /* Just drop the extra constants for now. * Ideally we should not have allowed the app to create a shader * that exceeds our constant buffer size but there's no way to * express that in gallium at this time. */ - count = CB_MAX - offset; + count = SVGA3D_CONSTREG_MAX - offset; } i = 0; diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index a37e1f8128b..a4d56bd7394 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -24,6 +24,7 @@ **********************************************************/ #include "util/u_inlines.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -40,6 +41,7 @@ struct rs_queue { #define EMIT_RS(svga, value, token, fail) \ do { \ + assert(SVGA3D_RS_##token < Elements(svga->state.hw_draw.rs)); \ if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \ svga_queue_rs( &queue, SVGA3D_RS_##token, value ); \ svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \ @@ -49,6 +51,7 @@ do { \ #define EMIT_RS_FLOAT(svga, fvalue, token, fail) \ do { \ unsigned value = fui(fvalue); \ + assert(SVGA3D_RS_##token < Elements(svga->state.hw_draw.rs)); \ if (svga->state.hw_draw.rs[SVGA3D_RS_##token] != value) { \ svga_queue_rs( &queue, SVGA3D_RS_##token, value ); \ svga->state.hw_draw.rs[SVGA3D_RS_##token] = value; \ diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index 8b11a2a425e..8dc51b70780 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -24,6 +24,7 @@ **********************************************************/ #include "util/u_inlines.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "util/u_math.h" @@ -249,6 +250,8 @@ struct ts_queue { #define EMIT_TS(svga, unit, val, token, fail) \ do { \ + assert(unit < Elements(svga->state.hw_draw.ts)); \ + assert(SVGA3D_TS_##token < Elements(svga->state.hw_draw.ts[unit])); \ if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \ svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ @@ -258,6 +261,8 @@ do { \ #define EMIT_TS_FLOAT(svga, unit, fvalue, token, fail) \ do { \ unsigned val = fui(fvalue); \ + assert(unit < Elements(svga->state.hw_draw.ts)); \ + assert(SVGA3D_TS_##token < Elements(svga->state.hw_draw.ts[unit])); \ if (svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] != val) { \ svga_queue_tss( &queue, unit, SVGA3D_TS_##token, val ); \ svga->state.hw_draw.ts[unit][SVGA3D_TS_##token] = val; \ -- 2.30.2