From adbe794a4628721c4b7976c89dac8f63b08963e7 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 13 Jan 2019 02:55:44 +0100 Subject: [PATCH] Properly access sym_attrs in corner cases the direct access to the sym_attrs[] array in the backends is out of bounds and replacec garbage symindices into the relocs. --- arm-link.c | 2 +- arm64-link.c | 4 ++-- i386-link.c | 6 +++--- x86_64-gen.c | 2 +- x86_64-link.c | 12 ++++++------ 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arm-link.c b/arm-link.c index 92a24eba..3e37ec82 100644 --- a/arm-link.c +++ b/arm-link.c @@ -365,7 +365,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t return; case R_ARM_GOT32: /* we load the got offset */ - *(int *)ptr += s1->sym_attrs[sym_index].got_offset; + *(int *)ptr += get_sym_attr(s1, sym_index, 0)->got_offset; return; case R_ARM_COPY: return; diff --git a/arm64-link.c b/arm64-link.c index 59322c55..a46fffca 100644 --- a/arm64-link.c +++ b/arm64-link.c @@ -215,7 +215,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_AARCH64_ADR_GOT_PAGE: { uint64_t off = (((s1->got->sh_addr + - s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12)); + get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12)); if ((off + ((uint64_t)1 << 20)) >> 21) tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); write32le(ptr, ((read32le(ptr) & 0x9f00001f) | @@ -226,7 +226,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t write32le(ptr, ((read32le(ptr) & 0xfff803ff) | ((s1->got->sh_addr + - s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7)); + get_sym_attr(s1, sym_index, 0)->got_offset) & 0xff8) << 7)); return; case R_AARCH64_COPY: return; diff --git a/i386-link.c b/i386-link.c index aea3c214..e467a4ea 100644 --- a/i386-link.c +++ b/i386-link.c @@ -169,7 +169,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t switch (type) { case R_386_32: if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->sym_attrs[sym_index].dyn_index; + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; qrel->r_offset = rel->r_offset; if (esym_index) { qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); @@ -185,7 +185,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_386_PC32: if (s1->output_type == TCC_OUTPUT_DLL) { /* DLL relocation */ - esym_index = s1->sym_attrs[sym_index].dyn_index; + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; if (esym_index) { qrel->r_offset = rel->r_offset; qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); @@ -211,7 +211,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_386_GOT32: case R_386_GOT32X: /* we load the got offset */ - add32le(ptr, s1->sym_attrs[sym_index].got_offset); + add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset); return; case R_386_16: if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { diff --git a/x86_64-gen.c b/x86_64-gen.c index e3969665..e41a6e84 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -625,7 +625,7 @@ static void gcall_or_jmp(int is_jmp) if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && ((vtop->r & VT_SYM) && (vtop->c.i-4) == (int)(vtop->c.i-4))) { /* constant symbolic case -> simple relocation */ - greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4)); + greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4)); oad(0xe8 + is_jmp, 0); /* call/jmp im */ } else { /* otherwise, indirect call */ diff --git a/x86_64-link.c b/x86_64-link.c index a96144c7..9210a25e 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t switch (type) { case R_X86_64_64: if (s1->output_type == TCC_OUTPUT_DLL) { - esym_index = s1->sym_attrs[sym_index].dyn_index; + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; qrel->r_offset = rel->r_offset; if (esym_index) { qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); @@ -210,7 +210,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_X86_64_PC32: if (s1->output_type == TCC_OUTPUT_DLL) { /* DLL relocation */ - esym_index = s1->sym_attrs[sym_index].dyn_index; + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; if (esym_index) { qrel->r_offset = rel->r_offset; qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); @@ -243,7 +243,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_X86_64_PC64: if (s1->output_type == TCC_OUTPUT_DLL) { /* DLL relocation */ - esym_index = s1->sym_attrs[sym_index].dyn_index; + esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index; if (esym_index) { qrel->r_offset = rel->r_offset; qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64); @@ -264,7 +264,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t case R_X86_64_GOTPCRELX: case R_X86_64_REX_GOTPCRELX: add32le(ptr, s1->got->sh_addr - addr + - s1->sym_attrs[sym_index].got_offset - 4); + get_sym_attr(s1, sym_index, 0)->got_offset - 4); break; case R_X86_64_GOTPC32: add32le(ptr, s1->got->sh_addr - addr + rel->r_addend); @@ -277,11 +277,11 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t break; case R_X86_64_GOT32: /* we load the got offset */ - add32le(ptr, s1->sym_attrs[sym_index].got_offset); + add32le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset); break; case R_X86_64_GOT64: /* we load the got offset */ - add64le(ptr, s1->sym_attrs[sym_index].got_offset); + add64le(ptr, get_sym_attr(s1, sym_index, 0)->got_offset); break; case R_X86_64_GOTOFF64: add64le(ptr, val - s1->got->sh_addr);