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.
This commit is contained in:
Michael Matz 2019-01-13 02:55:44 +01:00
parent d44d8cdf60
commit adbe794a46
5 changed files with 13 additions and 13 deletions

View file

@ -365,7 +365,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
return; return;
case R_ARM_GOT32: case R_ARM_GOT32:
/* we load the got offset */ /* 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; return;
case R_ARM_COPY: case R_ARM_COPY:
return; return;

View file

@ -215,7 +215,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
case R_AARCH64_ADR_GOT_PAGE: { case R_AARCH64_ADR_GOT_PAGE: {
uint64_t off = uint64_t off =
(((s1->got->sh_addr + (((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) if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed"); tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) | 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, write32le(ptr,
((read32le(ptr) & 0xfff803ff) | ((read32le(ptr) & 0xfff803ff) |
((s1->got->sh_addr + ((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; return;
case R_AARCH64_COPY: case R_AARCH64_COPY:
return; return;

View file

@ -169,7 +169,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
switch (type) { switch (type) {
case R_386_32: case R_386_32:
if (s1->output_type == TCC_OUTPUT_DLL) { 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; qrel->r_offset = rel->r_offset;
if (esym_index) { if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32); 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: case R_386_PC32:
if (s1->output_type == TCC_OUTPUT_DLL) { if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */ /* 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) { if (esym_index) {
qrel->r_offset = rel->r_offset; qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32); 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_GOT32:
case R_386_GOT32X: case R_386_GOT32X:
/* we load the got offset */ /* 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; return;
case R_386_16: case R_386_16:
if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {

View file

@ -625,7 +625,7 @@ static void gcall_or_jmp(int is_jmp)
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((vtop->r & VT_SYM) && (vtop->c.i-4) == (int)(vtop->c.i-4))) { ((vtop->r & VT_SYM) && (vtop->c.i-4) == (int)(vtop->c.i-4))) {
/* constant symbolic case -> simple relocation */ /* 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 */ oad(0xe8 + is_jmp, 0); /* call/jmp im */
} else { } else {
/* otherwise, indirect call */ /* otherwise, indirect call */

View file

@ -179,7 +179,7 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t
switch (type) { switch (type) {
case R_X86_64_64: case R_X86_64_64:
if (s1->output_type == TCC_OUTPUT_DLL) { 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; qrel->r_offset = rel->r_offset;
if (esym_index) { if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); 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: case R_X86_64_PC32:
if (s1->output_type == TCC_OUTPUT_DLL) { if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */ /* 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) { if (esym_index) {
qrel->r_offset = rel->r_offset; qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32); 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: case R_X86_64_PC64:
if (s1->output_type == TCC_OUTPUT_DLL) { if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */ /* 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) { if (esym_index) {
qrel->r_offset = rel->r_offset; qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64); 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_GOTPCRELX:
case R_X86_64_REX_GOTPCRELX: case R_X86_64_REX_GOTPCRELX:
add32le(ptr, s1->got->sh_addr - addr + 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; break;
case R_X86_64_GOTPC32: case R_X86_64_GOTPC32:
add32le(ptr, s1->got->sh_addr - addr + rel->r_addend); 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; break;
case R_X86_64_GOT32: case R_X86_64_GOT32:
/* we load the got offset */ /* 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; break;
case R_X86_64_GOT64: case R_X86_64_GOT64:
/* we load the got offset */ /* 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; break;
case R_X86_64_GOTOFF64: case R_X86_64_GOTOFF64:
add64le(ptr, val - s1->got->sh_addr); add64le(ptr, val - s1->got->sh_addr);