From 0b4836f2cd2f3312d4b4aa0c278c751b0784144c Mon Sep 17 00:00:00 2001 From: Mike Dodd Date: Tue, 14 Dec 2010 12:16:23 -0800 Subject: 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 --- debuggerd/symbol_table.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/debuggerd/symbol_table.c b/debuggerd/symbol_table.c index e76df3355..fd008fe29 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); -- cgit v1.2.3