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;
 | 
			
		||||
        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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue