summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2010-08-02 12:49:20 -0700
committerIan Romanick <[email protected]>2010-08-02 13:53:32 -0700
commit955ceef47f2bb8b5005abf11d4a8580c71f19e1b (patch)
tree339e3ab1b2207fafd13f51fb4847f161f1061a49
parent7ffe40532f6b22d9b80caeac0fc3b9495619186a (diff)
Keep a local copy of the symbol name in the symbol table
The symbol_header structure that tracks symbols with a particular name may have a different (longer) life time than the symbols it tracks. Not keeping a local copy of the name can lead to use-after-free errors. For example, the following sequence would trigger such an error: char *copy = strdup(name); _mesa_symbol_table_push_scope(st); _mesa_symbol_table_add_symbol(st, 0, name, NULL); _mesa_symbol_table_pop_scope(st); free(name); _mesa_symbol_table_find_symbol(st, 0, copy); With this change, the symbol table keeps a local copy of the name that has the same life time as the symbol_header for that name. This resolves some use-after-free errors with built-in functions in the GLSL compiler.
-rw-r--r--src/mesa/program/symbol_table.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/mesa/program/symbol_table.c b/src/mesa/program/symbol_table.c
index 3fea5ee1f1f..09e7cb44ef3 100644
--- a/src/mesa/program/symbol_table.c
+++ b/src/mesa/program/symbol_table.c
@@ -75,7 +75,7 @@ struct symbol_header {
struct symbol_header *next;
/** Symbol name. */
- const char *name;
+ char *name;
/** Linked list of symbols with the same name. */
struct symbol *symbols;
@@ -337,9 +337,9 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
if (hdr == NULL) {
hdr = calloc(1, sizeof(*hdr));
- hdr->name = name;
+ hdr->name = strdup(name);
- hash_table_insert(table->ht, hdr, name);
+ hash_table_insert(table->ht, hdr, hdr->name);
hdr->next = table->hdr;
table->hdr = hdr;
}
@@ -404,6 +404,7 @@ _mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
for (hdr = table->hdr; hdr != NULL; hdr = next) {
next = hdr->next;
+ free(hdr->name);
free(hdr);
}