summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2011-03-31 14:40:25 +0100
committerJosé Fonseca <[email protected]>2011-04-01 20:18:18 +0100
commit3733da31e8b4405b65e1b6ca3b6599ecc5af5fe7 (patch)
tree48e13947e294409416ddfa27f0f3458bf8bb54f9 /src/gallium/auxiliary/draw
parent4a7f013f9db793dab8dbc9f71646dab49f12ed2f (diff)
draw: Prevent out-of-bounds vertex buffer access.
Based on some code and ideas from Keith Whitwell.
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vsplit.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h12
7 files changed, 37 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index db2e3c5410d..b7d693f8584 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -146,6 +146,14 @@ struct draw_context
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_buffers;
+ /*
+ * This is the largest legal index value for the current set of
+ * bound vertex buffers. Regardless of any other consideration,
+ * all vertex lookups need to be clamped to 0..max_index to
+ * prevent out-of-bound access.
+ */
+ unsigned max_index;
+
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned nr_vertex_elements;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index c3d7e871f7a..e0eda67c1a2 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -470,6 +470,17 @@ draw_vbo(struct draw_context *draw,
if (0)
draw_print_arrays(draw, info->mode, info->start, MIN2(info->count, 20));
+ draw->pt.max_index = util_draw_max_index(draw->pt.vertex_buffer,
+ draw->pt.nr_vertex_buffers,
+ draw->pt.vertex_element,
+ draw->pt.nr_vertex_elements,
+ info);
+
+ /*
+ * TODO: We could use draw->pt.max_index to further narrow
+ * the min_index/max_index hints given by the state tracker.
+ */
+
for (instance = 0; instance < info->instance_count; instance++) {
draw->instance_id = instance + info->start_instance;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 4fa3b265e10..5589a8212e4 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -139,7 +139,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
((char *)draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.user.max_index);
+ draw->pt.max_index);
}
translate->run_elts( translate,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 51043102a61..0ab11d015c6 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -186,7 +186,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
((char *)draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.user.max_index);
+ draw->pt.max_index);
}
*max_vertices = (draw->render->max_vertex_buffer_bytes /
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index 1e926fb028e..0dbbfe2b73c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -169,7 +169,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
((const ubyte *) draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.user.max_index );
+ draw->pt.max_index );
}
*max_vertices = (draw->render->max_vertex_buffer_bytes /
diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit.c b/src/gallium/auxiliary/draw/draw_pt_vsplit.c
index a6875253094..c19dcd9e1f7 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vsplit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vsplit.c
@@ -85,7 +85,12 @@ vsplit_flush_cache(struct vsplit_frontend *vsplit, unsigned flags)
static INLINE void
vsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch)
{
- unsigned hash = fetch % MAP_SIZE;
+ struct draw_context *draw = vsplit->draw;
+ unsigned hash;
+
+ fetch = MIN2(fetch, draw->pt.max_index);
+
+ hash = fetch % MAP_SIZE;
if (vsplit->cache.fetches[hash] != fetch) {
/* update cache */
diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
index 10842a36e8a..e9714c1b3fa 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
@@ -56,7 +56,9 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
for (i = 0; i < icount; i++) {
ELT_TYPE idx = ib[i];
- assert(idx >= min_index && idx <= max_index);
+ if (idx >= min_index && idx <= max_index) {
+ debug_printf("warning: index out of range\n");
+ }
}
draw_elts = (const ushort *) ib;
}
@@ -87,7 +89,9 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
for (i = 0; i < icount; i++) {
ELT_TYPE idx = ib[i];
- assert(idx >= min_index && idx <= max_index);
+ if (idx >= min_index && idx <= max_index) {
+ debug_printf("warning: index out of range\n");
+ }
vsplit->draw_elts[i] = (ushort) idx;
}
}
@@ -95,7 +99,9 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
for (i = 0; i < icount; i++) {
ELT_TYPE idx = ib[i];
- assert(idx >= min_index && idx <= max_index);
+ if (idx >= min_index && idx <= max_index) {
+ debug_printf("warning: index out of range\n");
+ }
vsplit->draw_elts[i] = (ushort) (idx - min_index);
}
}