Hi Rusty, Today's linux-next merge of the rr tree got a conflict in arch/mips/kernel/module.c between commit c54de490a2e4 ("MIPS: Module: Deal with malformed HI16/LO16 relocation sequences") from the mips tree and commit 9db0bbe072c8 ("MIPS: Fix module.c build for 32 bit") from the rr tree. Just context changes (I think). I fixed it up (see below) and can carry the fix as necessary. -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx diff --cc arch/mips/kernel/module.c index 4f8c3cb,8ffd089..0000000 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@@ -132,25 -107,6 +105,17 @@@ static int apply_r_mips_hi16_rel(struc return 0; } - static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) - { - *location = (*location & 0xffff0000) | - ((((long long) v + 0x8000LL) >> 16) & 0xffff); - - return 0; - } - +static void free_relocation_chain(struct mips_hi16 *l) +{ + struct mips_hi16 *next; + + while (l) { + next = l->next; + kfree(l); + l = next; + } +} + static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) { unsigned long insnlo = *location; @@@ -308,61 -217,9 +229,22 @@@ int apply_relocate(Elf_Shdr *sechdrs, c return res; } + /* + * Normally the hi16 list should be deallocated at this point. A + * malformed binary however could contain a series of R_MIPS_HI16 + * relocations not followed by a R_MIPS_LO16 relocation. In that + * case, free up the list and return an error. + */ + if (me->arch.r_mips_hi16_list) { + free_relocation_chain(me->arch.r_mips_hi16_list); + me->arch.r_mips_hi16_list = NULL; + + return -ENOEXEC; + } + return 0; } - - int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, - struct module *me) - { - Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; - Elf_Sym *sym; - u32 *location; - unsigned int i; - Elf_Addr v; - int res; - - pr_debug("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); - - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr - + rel[i].r_offset; - /* This is the symbol it is referring to */ - sym = (Elf_Sym *)sechdrs[symindex].sh_addr - + ELF_MIPS_R_SYM(rel[i]); - if (IS_ERR_VALUE(sym->st_value)) { - /* Ignore unresolved weak symbol */ - if (ELF_ST_BIND(sym->st_info) == STB_WEAK) - continue; - printk(KERN_WARNING "%s: Unknown symbol %s\n", - me->name, strtab + sym->st_name); - return -ENOENT; - } - - v = sym->st_value + rel[i].r_addend; - - res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); - if (res) - return res; - } - - return 0; - } + #endif /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_dbetables(unsigned long addr)
Attachment:
pgp2elIDkvpsg.pgp
Description: PGP signature