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:
		
							parent
							
								
									d44d8cdf60
								
							
						
					
					
						commit
						adbe794a46
					
				
					 5 changed files with 13 additions and 13 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue