diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2009-08-03 12:26:40 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-08-03 17:52:49 +0100 |
commit | 477c4b07406357ad93d0e32788dbf3ee814eadaa (patch) | |
tree | 42164d744d8cbd1c0c56550a6b993d643f2c29e2 /arch/mips | |
parent | e2a9cf96a0af24f33206b4bb98cc3a12242260c1 (diff) | |
download | op-kernel-dev-477c4b07406357ad93d0e32788dbf3ee814eadaa.zip op-kernel-dev-477c4b07406357ad93d0e32788dbf3ee814eadaa.tar.gz |
MIPS: VPE: Free relocation chain on error.
This may happen if a bad sequence of relocations is being encountered.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/vpe.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3d4ef84..245b03e 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -462,16 +462,15 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, { unsigned long insnlo = *location; Elf32_Addr val, vallo; + struct mips_hi16 *l, *next; /* Sign extend the addend we extract from the lo insn. */ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; if (mips_hi16_list != NULL) { - struct mips_hi16 *l; l = mips_hi16_list; while (l != NULL) { - struct mips_hi16 *next; unsigned long insn; /* @@ -481,7 +480,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, printk(KERN_DEBUG "VPE loader: " "apply_r_mips_lo16/hi16: \t" "inconsistent value information\n"); - return -ENOEXEC; + goto out_free; } /* @@ -519,6 +518,16 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, *location = insnlo; return 0; + +out_free: + while (l != NULL) { + next = l->next; + kfree(l); + l = next; + } + mips_hi16_list = NULL; + + return -ENOEXEC; } static int (*reloc_handlers[]) (struct module *me, uint32_t *location, |