MIPS: module: Ensure we always clean up r_mips_hi16_list
If we hit an error whilst processing a reloc then we would return early from apply_relocate & potentially not free entries in r_mips_hi16_list, thereby leaking memory. Fix this by ensuring that we always run the code to free r_mipps_hi16_list when errors occur. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Fixes:861667dc82
("MIPS: Fix race condition in module relocation code.") Fixes:04211a5746
("MIPS: Bail on unsupported module relocs") Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/15831/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Родитель
59baa24d87
Коммит
351b0940d4
|
@ -251,7 +251,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
|||
u32 *location;
|
||||
unsigned int i, type;
|
||||
Elf_Addr v;
|
||||
int res;
|
||||
int err = 0;
|
||||
|
||||
pr_debug("Applying relocate section %u to %u\n", relsec,
|
||||
sechdrs[relsec].sh_info);
|
||||
|
@ -270,7 +270,8 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
|||
continue;
|
||||
pr_warn("%s: Unknown symbol %s\n",
|
||||
me->name, strtab + sym->st_name);
|
||||
return -ENOENT;
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
type = ELF_MIPS_R_TYPE(rel[i]);
|
||||
|
@ -283,29 +284,32 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
|||
if (!handler) {
|
||||
pr_err("%s: Unknown relocation type %u\n",
|
||||
me->name, type);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
v = sym->st_value;
|
||||
res = handler(me, location, v);
|
||||
if (res)
|
||||
return res;
|
||||
err = handler(me, location, v);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* Normally the hi16 list should be deallocated at this point. A
|
||||
* 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.
|
||||
* relocations not followed by a R_MIPS_LO16 relocation, or if we hit
|
||||
* an error processing a reloc we might have gotten here before
|
||||
* reaching the R_MIPS_LO16. In either 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;
|
||||
err = err ?: -ENOEXEC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Given an address, look for it in the module exception tables. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче