From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755608AbcBCDpl (ORCPT ); Tue, 2 Feb 2016 22:45:41 -0500 Received: from mailapp01.imgtec.com ([195.59.15.196]:36812 "EHLO mailapp01.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755514AbcBCDpS (ORCPT ); Tue, 2 Feb 2016 22:45:18 -0500 From: Paul Burton To: , Ralf Baechle CC: Paul Burton , James Hogan , Andrey Konovalov , "Steven J. Hill" , Andrey Ryabinin , , Andrew Morton Subject: [PATCH 1/5] MIPS: Bail on unsupported module relocs Date: Wed, 3 Feb 2016 03:44:41 +0000 Message-ID: <1454471085-20963-2-git-send-email-paul.burton@imgtec.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1454471085-20963-1-git-send-email-paul.burton@imgtec.com> References: <1454471085-20963-1-git-send-email-paul.burton@imgtec.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.100.200.215] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When an unsupported reloc is encountered in a module, we currently blindly branch to whatever would be at its entry in the reloc handler function pointer arrays. This may be NULL, or if the unsupported reloc has a type greater than that of the supported reloc with the highest type then we'll dereference some value after the function pointer array & branch to that. The result is at best a kernel oops. Fix this by checking that the reloc type has an entry in the function pointer array (ie. is less than the number of items in the array) and that the handler is non-NULL, returning an error code to fail the module load if no handler is found. Signed-off-by: Paul Burton Cc: James Hogan --- arch/mips/kernel/module-rela.c | 19 ++++++++++++++++--- arch/mips/kernel/module.c | 19 ++++++++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c index 2b70723..769e316 100644 --- a/arch/mips/kernel/module-rela.c +++ b/arch/mips/kernel/module-rela.c @@ -109,9 +109,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, struct module *me) { Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; int res; @@ -134,9 +135,21 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - v = sym->st_value + rel[i].r_addend; + type = ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rela)) + handler = reloc_handlers_rela[type]; + else + handler = NULL; - res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); + if (!handler) { + pr_warn("%s: Unknown relocation type %u\n", + me->name, type); + return -EINVAL; + } + + v = sym->st_value + rel[i].r_addend; + res = handler(me, location, v); if (res) return res; } diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 1833f51..2adf572 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -197,9 +197,10 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, struct module *me) { Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; int res; @@ -223,9 +224,21 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - v = sym->st_value; + type = ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rel)) + handler = reloc_handlers_rel[type]; + else + handler = NULL; - res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v); + if (!handler) { + pr_warn("%s: Unknown relocation type %u\n", + me->name, type); + return -EINVAL; + } + + v = sym->st_value; + res = handler(me, location, v); if (res) return res; } -- 2.7.0