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;
|
u32 *location;
|
||||||
unsigned int i, type;
|
unsigned int i, type;
|
||||||
Elf_Addr v;
|
Elf_Addr v;
|
||||||
int res;
|
int err = 0;
|
||||||
|
|
||||||
pr_debug("Applying relocate section %u to %u\n", relsec,
|
pr_debug("Applying relocate section %u to %u\n", relsec,
|
||||||
sechdrs[relsec].sh_info);
|
sechdrs[relsec].sh_info);
|
||||||
|
@ -270,7 +270,8 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
continue;
|
continue;
|
||||||
pr_warn("%s: Unknown symbol %s\n",
|
pr_warn("%s: Unknown symbol %s\n",
|
||||||
me->name, strtab + sym->st_name);
|
me->name, strtab + sym->st_name);
|
||||||
return -ENOENT;
|
err = -ENOENT;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = ELF_MIPS_R_TYPE(rel[i]);
|
type = ELF_MIPS_R_TYPE(rel[i]);
|
||||||
|
@ -283,29 +284,32 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
pr_err("%s: Unknown relocation type %u\n",
|
pr_err("%s: Unknown relocation type %u\n",
|
||||||
me->name, type);
|
me->name, type);
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = sym->st_value;
|
v = sym->st_value;
|
||||||
res = handler(me, location, v);
|
err = handler(me, location, v);
|
||||||
if (res)
|
if (err)
|
||||||
return res;
|
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
|
* malformed binary however could contain a series of R_MIPS_HI16
|
||||||
* relocations not followed by a R_MIPS_LO16 relocation. In that
|
* relocations not followed by a R_MIPS_LO16 relocation, or if we hit
|
||||||
* case, free up the list and return an error.
|
* 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) {
|
if (me->arch.r_mips_hi16_list) {
|
||||||
free_relocation_chain(me->arch.r_mips_hi16_list);
|
free_relocation_chain(me->arch.r_mips_hi16_list);
|
||||||
me->arch.r_mips_hi16_list = NULL;
|
me->arch.r_mips_hi16_list = NULL;
|
||||||
|
err = err ?: -ENOEXEC;
|
||||||
return -ENOEXEC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given an address, look for it in the module exception tables. */
|
/* Given an address, look for it in the module exception tables. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче