summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Dodd <mdodd@google.com>2010-12-14 12:16:23 -0800
committerMike Dodd <mdodd@google.com>2010-12-14 12:16:23 -0800
commit584b8e30bc8e296f71bcd1cdad95e44c23b3e40f (patch)
tree54ea475a96a0b9a4f17cb7b7633396afd96d693f
parentec34ef58805a9dfe32da37210702c01ff0763f44 (diff)
downloadsystem_core-584b8e30bc8e296f71bcd1cdad95e44c23b3e40f.zip
system_core-584b8e30bc8e296f71bcd1cdad95e44c23b3e40f.tar.gz
system_core-584b8e30bc8e296f71bcd1cdad95e44c23b3e40f.tar.bz2
Fix debuggerd (native crash dump).
Change 44659e90f (6cc4923087 in AOSP) introduced walking both the symbol table and dynamic symbol table. The problem is that it was dereferencing values whether or not the two tables were both present, which could wind up reading from invalid memory. The read from a bad address would cause debuggerd itself to crash, which isn't handled. Change-Id: Ie936f660018b1980dee5b6ed669588db861f1a79
-rw-r--r--debuggerd/symbol_table.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/debuggerd/symbol_table.c b/debuggerd/symbol_table.c
index e76df33..fd008fe 100644
--- a/debuggerd/symbol_table.c
+++ b/debuggerd/symbol_table.c
@@ -94,17 +94,26 @@ struct symbol_table *symbol_table_create(const char *filename)
table->name = strdup(filename);
table->num_symbols = 0;
- Elf32_Sym *dynsyms = (Elf32_Sym*)(base + shdr[dynsym_idx].sh_offset);
- Elf32_Sym *syms = (Elf32_Sym*)(base + shdr[sym_idx].sh_offset);
+ Elf32_Sym *dynsyms = NULL;
+ Elf32_Sym *syms = NULL;
+ int dynnumsyms = 0;
+ int numsyms = 0;
+ char *dynstr = NULL;
+ char *str = NULL;
- int dynnumsyms = shdr[dynsym_idx].sh_size / shdr[dynsym_idx].sh_entsize;
- int numsyms = shdr[sym_idx].sh_size / shdr[sym_idx].sh_entsize;
-
- int dynstr_idx = shdr[dynsym_idx].sh_link;
- int str_idx = shdr[sym_idx].sh_link;
+ if (dynsym_idx != -1) {
+ dynsyms = (Elf32_Sym*)(base + shdr[dynsym_idx].sh_offset);
+ dynnumsyms = shdr[dynsym_idx].sh_size / shdr[dynsym_idx].sh_entsize;
+ int dynstr_idx = shdr[dynsym_idx].sh_link;
+ dynstr = base + shdr[dynstr_idx].sh_offset;
+ }
- char *dynstr = base + shdr[dynstr_idx].sh_offset;
- char *str = base + shdr[str_idx].sh_offset;
+ if (sym_idx != -1) {
+ syms = (Elf32_Sym*)(base + shdr[sym_idx].sh_offset);
+ numsyms = shdr[sym_idx].sh_size / shdr[sym_idx].sh_entsize;
+ int str_idx = shdr[sym_idx].sh_link;
+ str = base + shdr[str_idx].sh_offset;
+ }
int symbol_count = 0;
int dynsymbol_count = 0;
@@ -134,7 +143,7 @@ struct symbol_table *symbol_table_create(const char *filename)
}
// Now, create an entry in our symbol table structure for each symbol...
- table->num_symbols += symbol_count + dynsymbol_count;;
+ table->num_symbols += symbol_count + dynsymbol_count;
table->symbols = malloc(table->num_symbols * sizeof(struct symbol));
if(!table->symbols) {
free(table);