translate: fix buffer overflows
authorZack Rusin <zackr@vmware.com>
Tue, 4 Mar 2014 04:09:58 +0000 (23:09 -0500)
committerZack Rusin <zackr@vmware.com>
Tue, 4 Mar 2014 20:56:04 +0000 (15:56 -0500)
Because in draw we always inject position at slot 0 whenever
fragment shader would take the maximum number of inputs (32) it
meant that we had PIPE_MAX_ATTRIBS + 1 slots to translate, which
meant that we were crashing with fragment shaders that took
the maximum number of attributes as inputs. The actual max number
of attributes we need to translate thus is PIPE_MAX_ATTRIBS + 1.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Matthew McClure <mcclurem@vmware.com>
src/gallium/auxiliary/translate/translate.h
src/gallium/auxiliary/translate/translate_cache.c
src/gallium/auxiliary/translate/translate_generic.c
src/gallium/auxiliary/translate/translate_sse.c

index d5f23b83905623e993772ba7731cc18ba9d68175..7fe8ff8145f3c9bb10d509e1f65c4e26f07e7749 100644 (file)
 #include "pipe/p_format.h"
 #include "pipe/p_state.h"
 
+/**
+ * Translate has to work on one more attribute because
+ * the draw module has to be able to pass the vertex
+ * position even if the fragment shader already consumes
+ * PIPE_MAX_ATTRIBS inputs.
+ */
+#define TRANSLATE_MAX_ATTRIBS (PIPE_MAX_ATTRIBS + 1)
+
 enum translate_element_type {
    TRANSLATE_ELEMENT_NORMAL,
    TRANSLATE_ELEMENT_INSTANCE_ID
@@ -64,7 +72,7 @@ struct translate_element
 struct translate_key {
    unsigned output_stride;
    unsigned nr_elements;
-   struct translate_element element[PIPE_MAX_ATTRIBS + 1];
+   struct translate_element element[TRANSLATE_MAX_ATTRIBS];
 };
 
 
index 2c1c114607221cfdb83fe88734b1c66b463c7fcb..bb8bdcb58c41186470c562a589179ff0b37f5dca 100644 (file)
@@ -73,7 +73,7 @@ void translate_cache_destroy(struct translate_cache *cache)
 static INLINE unsigned translate_hash_key_size(struct translate_key *key)
 {
    unsigned size = sizeof(struct translate_key) -
-                   sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements);
+                   sizeof(struct translate_element) * (TRANSLATE_MAX_ATTRIBS - key->nr_elements);
    return size;
 }
 
index 5ffce32ba7014fdfeacf1ad5e4eb0ce701ada5ef..26b87c5af1c9621ca7d41c74dc0eb3c42e6258ef 100644 (file)
@@ -73,7 +73,7 @@ struct translate_generic {
        */
       int copy_size;
 
-   } attrib[PIPE_MAX_ATTRIBS];
+   } attrib[TRANSLATE_MAX_ATTRIBS];
 
    unsigned nr_attrib;
 };
@@ -799,6 +799,8 @@ struct translate *translate_generic_create( const struct translate_key *key )
    if (tg == NULL)
       return NULL;
 
+   assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS);
+
    tg->translate.key = *key;
    tg->translate.release = generic_release;
    tg->translate.set_buffer = generic_set_buffer;
index b6bc22227d683254129b1cd3f6b52a54e9b2c181..1b698cd7c7c30917a2759242e37a90ea9860f052 100644 (file)
@@ -104,15 +104,15 @@ struct translate_sse
    int8_t reg_to_const[16];
    int8_t const_to_reg[NUM_CONSTS];
 
-   struct translate_buffer buffer[PIPE_MAX_ATTRIBS];
+   struct translate_buffer buffer[TRANSLATE_MAX_ATTRIBS];
    unsigned nr_buffers;
 
    /* Multiple buffer variants can map to a single buffer. */
-   struct translate_buffer_variant buffer_variant[PIPE_MAX_ATTRIBS];
+   struct translate_buffer_variant buffer_variant[TRANSLATE_MAX_ATTRIBS];
    unsigned nr_buffer_variants;
 
    /* Multiple elements can map to a single buffer variant. */
-   unsigned element_to_buffer_variant[PIPE_MAX_ATTRIBS];
+   unsigned element_to_buffer_variant[TRANSLATE_MAX_ATTRIBS];
 
    boolean use_instancing;
    unsigned instance_id;
@@ -1494,6 +1494,8 @@ translate_sse2_create(const struct translate_key *key)
    p->translate.release = translate_sse_release;
    p->translate.set_buffer = translate_sse_set_buffer;
 
+   assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS);
+
    for (i = 0; i < key->nr_elements; i++) {
       if (key->element[i].type == TRANSLATE_ELEMENT_NORMAL) {
          unsigned j;