From c99af3752bb52ba3aece5315279a57a477edfaf1 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Fri, 22 Jun 2012 13:49:31 -0400 Subject: module: taint kernel when lve module is loaded Cloudlinux have a product called lve that includes a kernel module. This was previously GPLed but is now under a proprietary license, but the module continues to declare MODULE_LICENSE("GPL") and makes use of some EXPORT_SYMBOL_GPL symbols. Forcibly taint it in order to avoid this. Signed-off-by: Matthew Garrett Cc: Alex Lyashkov Signed-off-by: Rusty Russell Cc: stable@kernel.org --- kernel/module.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/module.c b/kernel/module.c index 4edbd9c11aca..9ad9ee9406d6 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2730,6 +2730,10 @@ static int check_module_license_and_versions(struct module *mod) if (strcmp(mod->name, "driverloader") == 0) add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + /* lve claims to be GPL but upstream won't provide source */ + if (strcmp(mod->name, "lve") == 0) + add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + #ifdef CONFIG_MODVERSIONS if ((mod->num_syms && !mod->crcs) || (mod->num_gpl_syms && !mod->gpl_crcs) -- cgit v1.2.3 From 6ede81239e31cfacbb1e2d260530cd80d13cf0db Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 14 Aug 2012 17:13:45 +0200 Subject: MIPS: Fix module.c build for 32 bit Fixes build failure introduced by "Make most arch asm/module.h files use asm-generic/module.h" by moving all the RELA processing code to a separate file to be used only for RELA processing on 64-bit kernels. CC arch/mips/kernel/module.o arch/mips/kernel/module.c:250:14: error: 'reloc_handlers_rela' defined but not used [-Werror=unused-variable] cc1: all warnings being treated as errors make[6]: *** [arch/mips/kernel/module.o] Error 1 Signed-off-by: Ralf Baechle Signed-off-by: Rusty Russell --- arch/mips/kernel/Makefile | 1 + arch/mips/kernel/module-rela.c | 145 +++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/module.c | 121 +--------------------------------- 3 files changed, 147 insertions(+), 120 deletions(-) create mode 100644 arch/mips/kernel/module-rela.c diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index fdaf65e1a99d..e2c14999839a 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o +obj-$(CONFIG_MODULES) += module-rela.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c new file mode 100644 index 000000000000..61d60028b888 --- /dev/null +++ b/arch/mips/kernel/module-rela.c @@ -0,0 +1,145 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2001 Rusty Russell. + * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2005 Thiemo Seufer + */ + +#include +#include +#include +#include + +extern int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v); + +static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) +{ + *location = v; + + return 0; +} + +static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) +{ + if (v % 4) { + pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", + me->name); + return -ENOEXEC; + } + + if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { + printk(KERN_ERR + "module %s: relocation overflow\n", + me->name); + return -ENOEXEC; + } + + *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); + + 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 int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) +{ + *location = (*location & 0xffff0000) | (v & 0xffff); + + return 0; +} + +static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) +{ + *(Elf_Addr *)location = v; + + return 0; +} + +static int apply_r_mips_higher_rela(struct module *me, u32 *location, + Elf_Addr v) +{ + *location = (*location & 0xffff0000) | + ((((long long) v + 0x80008000LL) >> 32) & 0xffff); + + return 0; +} + +static int apply_r_mips_highest_rela(struct module *me, u32 *location, + Elf_Addr v) +{ + *location = (*location & 0xffff0000) | + ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); + + return 0; +} + +static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, + Elf_Addr v) = { + [R_MIPS_NONE] = apply_r_mips_none, + [R_MIPS_32] = apply_r_mips_32_rela, + [R_MIPS_26] = apply_r_mips_26_rela, + [R_MIPS_HI16] = apply_r_mips_hi16_rela, + [R_MIPS_LO16] = apply_r_mips_lo16_rela, + [R_MIPS_64] = apply_r_mips_64_rela, + [R_MIPS_HIGHER] = apply_r_mips_higher_rela, + [R_MIPS_HIGHEST] = apply_r_mips_highest_rela +}; + +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; +} diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 4f8c3cba8c0c..07ff5812ffaf 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -51,7 +51,7 @@ void *module_alloc(unsigned long size) } #endif -static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) +int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) { return 0; } @@ -63,13 +63,6 @@ static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v) return 0; } -static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) -{ - *location = v; - - return 0; -} - static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) { if (v % 4) { @@ -91,26 +84,6 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) return 0; } -static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) -{ - if (v % 4) { - pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", - me->name); - return -ENOEXEC; - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { - printk(KERN_ERR - "module %s: relocation overflow\n", - me->name); - return -ENOEXEC; - } - - *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); - - return 0; -} - static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) { struct mips_hi16 *n; @@ -132,14 +105,6 @@ static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) 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; @@ -217,38 +182,6 @@ out_danger: return -ENOEXEC; } -static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) -{ - *location = (*location & 0xffff0000) | (v & 0xffff); - - return 0; -} - -static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) -{ - *(Elf_Addr *)location = v; - - return 0; -} - -static int apply_r_mips_higher_rela(struct module *me, u32 *location, - Elf_Addr v) -{ - *location = (*location & 0xffff0000) | - ((((long long) v + 0x80008000LL) >> 32) & 0xffff); - - return 0; -} - -static int apply_r_mips_highest_rela(struct module *me, u32 *location, - Elf_Addr v) -{ - *location = (*location & 0xffff0000) | - ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); - - return 0; -} - static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, Elf_Addr v) = { [R_MIPS_NONE] = apply_r_mips_none, @@ -258,18 +191,6 @@ static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, [R_MIPS_LO16] = apply_r_mips_lo16_rel }; -static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, - Elf_Addr v) = { - [R_MIPS_NONE] = apply_r_mips_none, - [R_MIPS_32] = apply_r_mips_32_rela, - [R_MIPS_26] = apply_r_mips_26_rela, - [R_MIPS_HI16] = apply_r_mips_hi16_rela, - [R_MIPS_LO16] = apply_r_mips_lo16_rela, - [R_MIPS_64] = apply_r_mips_64_rela, - [R_MIPS_HIGHER] = apply_r_mips_higher_rela, - [R_MIPS_HIGHEST] = apply_r_mips_highest_rela -}; - int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *me) @@ -324,46 +245,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, 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; -} - /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_dbetables(unsigned long addr) { -- cgit v1.2.3 From 786d35d45cc40b2a51a18f73e14e135d47fdced7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 28 Sep 2012 14:31:03 +0930 Subject: Make most arch asm/module.h files use asm-generic/module.h Use the mapping of Elf_[SPE]hdr, Elf_Addr, Elf_Sym, Elf_Dyn, Elf_Rel/Rela, ELF_R_TYPE() and ELF_R_SYM() to either the 32-bit version or the 64-bit version into asm-generic/module.h for all arches bar MIPS. Also, use the generic definition mod_arch_specific where possible. To this end, I've defined three new config bools: (*) HAVE_MOD_ARCH_SPECIFIC Arches define this if they don't want to use the empty generic mod_arch_specific struct. (*) MODULES_USE_ELF_RELA Arches define this if their modules can contain RELA records. This causes the Elf_Rela mapping to be emitted and allows apply_relocate_add() to be defined by the arch rather than have the core emit an error message. (*) MODULES_USE_ELF_REL Arches define this if their modules can contain REL records. This causes the Elf_Rel mapping to be emitted and allows apply_relocate() to be defined by the arch rather than have the core emit an error message. Note that it is possible to allow both REL and RELA records: m68k and mips are two arches that do this. With this, some arch asm/module.h files can be deleted entirely and replaced with a generic-y marker in the arch Kbuild file. Additionally, I have removed the bits from m32r and score that handle the unsupported type of relocation record as that's now handled centrally. Signed-off-by: David Howells Acked-by: Sam Ravnborg Signed-off-by: Rusty Russell --- arch/Kconfig | 19 ++++++++++++++++++ arch/alpha/Kconfig | 2 ++ arch/alpha/include/asm/module.h | 10 ++-------- arch/arm/Kconfig | 2 ++ arch/arm/include/asm/module.h | 8 ++------ arch/avr32/Kconfig | 2 ++ arch/avr32/include/asm/module.h | 6 ++---- arch/blackfin/Kconfig | 2 ++ arch/blackfin/include/asm/module.h | 4 +--- arch/c6x/Kconfig | 1 + arch/c6x/include/asm/module.h | 12 +----------- arch/cris/Kconfig | 1 + arch/cris/include/asm/Kbuild | 2 ++ arch/cris/include/asm/module.h | 9 --------- arch/frv/include/asm/module.h | 8 +------- arch/h8300/Kconfig | 1 + arch/h8300/include/asm/Kbuild | 2 ++ arch/h8300/include/asm/module.h | 11 ----------- arch/hexagon/Kconfig | 1 + arch/ia64/Kconfig | 2 ++ arch/ia64/include/asm/module.h | 6 ++---- arch/m32r/Kconfig | 1 + arch/m32r/include/asm/Kbuild | 2 ++ arch/m32r/include/asm/module.h | 10 ---------- arch/m32r/kernel/module.c | 15 -------------- arch/m68k/Kconfig | 3 +++ arch/m68k/include/asm/module.h | 6 ++---- arch/microblaze/Kconfig | 1 + arch/mips/Kconfig | 3 +++ arch/mips/include/asm/module.h | 10 ++++++++-- arch/mips/kernel/Makefile | 2 +- arch/mn10300/Kconfig | 1 + arch/mn10300/include/asm/module.h | 7 +------ arch/openrisc/Kconfig | 1 + arch/parisc/Kconfig | 2 ++ arch/parisc/include/asm/module.h | 16 +++------------ arch/powerpc/Kconfig | 2 ++ arch/powerpc/include/asm/module.h | 7 +------ arch/s390/Kconfig | 2 ++ arch/s390/include/asm/module.h | 18 +++-------------- arch/score/Kconfig | 2 ++ arch/score/include/asm/module.h | 6 +----- arch/score/kernel/module.c | 10 ---------- arch/sh/Kconfig | 2 ++ arch/sh/include/asm/module.h | 14 +++---------- arch/sparc/Kconfig | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/sparc/include/asm/module.h | 24 ----------------------- arch/tile/Kconfig | 1 + arch/unicore32/Kconfig | 1 + arch/x86/Kconfig | 2 ++ arch/x86/um/Kconfig | 2 ++ arch/xtensa/Kconfig | 1 + arch/xtensa/include/asm/module.h | 9 +-------- include/asm-generic/module.h | 40 +++++++++++++++++++++++++++++++------- include/linux/moduleloader.h | 36 ++++++++++++++++++++++++++++++---- kernel/module.c | 20 ------------------- 57 files changed, 168 insertions(+), 224 deletions(-) delete mode 100644 arch/cris/include/asm/module.h delete mode 100644 arch/h8300/include/asm/module.h delete mode 100644 arch/m32r/include/asm/module.h delete mode 100644 arch/sparc/include/asm/module.h diff --git a/arch/Kconfig b/arch/Kconfig index 72f2fa189cc5..3450115c6437 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -281,4 +281,23 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_MOD_ARCH_SPECIFIC + bool + help + The arch uses struct mod_arch_specific to store data. Many arches + just need a simple module loader without arch specific data - those + should not enable this. + +config MODULES_USE_ELF_RELA + bool + help + Modules only use ELF RELA relocations. Modules with ELF REL + relocations will give an error. + +config MODULES_USE_ELF_REL + bool + help + Modules only use ELF REL relocations. Modules with ELF RELA + relocations will give an error. + source "kernel/gcov/Kconfig" diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 9944dedee5b1..7e3710c0cce5 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -20,6 +20,8 @@ config ALPHA select GENERIC_CMOS_UPDATE select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/alpha/include/asm/module.h b/arch/alpha/include/asm/module.h index 7b63743c534a..9cd13b55155f 100644 --- a/arch/alpha/include/asm/module.h +++ b/arch/alpha/include/asm/module.h @@ -1,19 +1,13 @@ #ifndef _ALPHA_MODULE_H #define _ALPHA_MODULE_H +#include + struct mod_arch_specific { unsigned int gotsecindex; }; -#define Elf_Sym Elf64_Sym -#define Elf_Shdr Elf64_Shdr -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Phdr Elf64_Phdr -#define Elf_Dyn Elf64_Dyn -#define Elf_Rel Elf64_Rel -#define Elf_Rela Elf64_Rela - #define ARCH_SHF_SMALL SHF_ALPHA_GPREL #ifdef MODULE diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2f88d8d97701..7a08b3a71c01 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -49,6 +49,8 @@ config ARM select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN + select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND + select MODULES_USE_ELF_REL help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index 6c6809f982f1..0d3a28dbc8e5 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h @@ -1,9 +1,7 @@ #ifndef _ASM_ARM_MODULE_H #define _ASM_ARM_MODULE_H -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#include struct unwind_table; @@ -16,13 +14,11 @@ enum { ARM_SEC_DEVEXIT, ARM_SEC_MAX, }; -#endif struct mod_arch_specific { -#ifdef CONFIG_ARM_UNWIND struct unwind_table *unwind[ARM_SEC_MAX]; -#endif }; +#endif /* * Add the ARM architecture version to the version magic string diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 5ade51c8a87f..06e73bf665e9 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -15,6 +15,8 @@ config AVR32 select ARCH_WANT_IPC_PARSE_VERSION select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular diff --git a/arch/avr32/include/asm/module.h b/arch/avr32/include/asm/module.h index 451444538a1b..3f083d385a64 100644 --- a/arch/avr32/include/asm/module.h +++ b/arch/avr32/include/asm/module.h @@ -1,6 +1,8 @@ #ifndef __ASM_AVR32_MODULE_H #define __ASM_AVR32_MODULE_H +#include + struct mod_arch_syminfo { unsigned long got_offset; int got_initialized; @@ -17,10 +19,6 @@ struct mod_arch_specific { struct mod_arch_syminfo *syminfo; }; -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - #define MODULE_PROC_FAMILY "AVR32v1" #define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c7092e6057c5..8e82e267b897 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -42,6 +42,8 @@ config BLACKFIN select HAVE_NMI_WATCHDOG if NMI_WATCHDOG select GENERIC_SMP_IDLE_THREAD select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA config GENERIC_CSUM def_bool y diff --git a/arch/blackfin/include/asm/module.h b/arch/blackfin/include/asm/module.h index ed5689b82c9f..231a149b3f77 100644 --- a/arch/blackfin/include/asm/module.h +++ b/arch/blackfin/include/asm/module.h @@ -7,9 +7,7 @@ #ifndef _ASM_BFIN_MODULE_H #define _ASM_BFIN_MODULE_H -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#include struct mod_arch_specific { Elf_Shdr *text_l1; diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 983c859e40b7..f6a3648f5ec3 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -17,6 +17,7 @@ config C6X select OF select OF_EARLY_FLATTREE select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA config MMU def_bool n diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h index a453f9744f42..5c7269c7ef73 100644 --- a/arch/c6x/include/asm/module.h +++ b/arch/c6x/include/asm/module.h @@ -13,17 +13,7 @@ #ifndef _ASM_C6X_MODULE_H #define _ASM_C6X_MODULE_H -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Addr Elf32_Addr -#define Elf_Word Elf32_Word - -/* - * This file contains the C6x architecture specific module code. - */ -struct mod_arch_specific { -}; +#include struct loaded_sections { unsigned int new_vaddr; diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index e92215428a37..7bb8cf90e6aa 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -47,6 +47,7 @@ config CRIS select GENERIC_IOMAP select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 select GENERIC_CMOS_UPDATE + select MODULES_USE_ELF_RELA config HZ int diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 04d02a51c5e9..28b690de7971 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -7,3 +7,5 @@ header-y += ethernet.h header-y += etraxgpio.h header-y += rs485.h header-y += sync_serial.h + +generic-y += module.h diff --git a/arch/cris/include/asm/module.h b/arch/cris/include/asm/module.h deleted file mode 100644 index 7ee72311bd78..000000000000 --- a/arch/cris/include/asm/module.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _ASM_CRIS_MODULE_H -#define _ASM_CRIS_MODULE_H -/* cris is simple */ -struct mod_arch_specific { }; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr -#endif /* _ASM_CRIS_MODULE_H */ diff --git a/arch/frv/include/asm/module.h b/arch/frv/include/asm/module.h index 3d5c6360289a..a8848f09a217 100644 --- a/arch/frv/include/asm/module.h +++ b/arch/frv/include/asm/module.h @@ -11,13 +11,7 @@ #ifndef _ASM_MODULE_H #define _ASM_MODULE_H -struct mod_arch_specific -{ -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#include /* * Include the architecture version. diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 5e8a0d9a09ce..c149d3b29eb6 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -6,6 +6,7 @@ config H8300 select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES + select MODULES_USE_ELF_RELA config SYMBOL_PREFIX string diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index c68e1680da01..871382d239fe 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -1 +1,3 @@ include include/asm-generic/Kbuild.asm + +generic-y += module.h diff --git a/arch/h8300/include/asm/module.h b/arch/h8300/include/asm/module.h deleted file mode 100644 index 8e46724b7c09..000000000000 --- a/arch/h8300/include/asm/module.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ASM_H8300_MODULE_H -#define _ASM_H8300_MODULE_H -/* - * This file contains the H8/300 architecture specific module code. - */ -struct mod_arch_specific { }; -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif /* _ASM_H8/300_MODULE_H */ diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index b2fdfb700f50..0744f7d7b1fd 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -30,6 +30,7 @@ config HEXAGON select KTIME_SCALAR select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS_BROADCAST + select MODULES_USE_ELF_RELA ---help--- Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 310cf5781fad..688146466d0d 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -39,6 +39,8 @@ config IA64 select ARCH_THREAD_INFO_ALLOCATOR select ARCH_CLOCKSOURCE_DATA select GENERIC_TIME_VSYSCALL + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h index 908eaef42a08..dfba22a872c3 100644 --- a/arch/ia64/include/asm/module.h +++ b/arch/ia64/include/asm/module.h @@ -1,6 +1,8 @@ #ifndef _ASM_IA64_MODULE_H #define _ASM_IA64_MODULE_H +#include + /* * IA-64-specific support for kernel module loader. * @@ -29,10 +31,6 @@ struct mod_arch_specific { unsigned int next_got_entry; /* index of next available got entry */ }; -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr - #define MODULE_PROC_FAMILY "ia64" #define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY \ "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__) diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 49498bbb9616..fc6153361bf5 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -13,6 +13,7 @@ config M32R select GENERIC_IRQ_SHOW select GENERIC_ATOMIC64 select ARCH_USES_GETTIMEOFFSET + select MODULES_USE_ELF_RELA config SBUS bool diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index c68e1680da01..871382d239fe 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -1 +1,3 @@ include include/asm-generic/Kbuild.asm + +generic-y += module.h diff --git a/arch/m32r/include/asm/module.h b/arch/m32r/include/asm/module.h deleted file mode 100644 index eb73ee011215..000000000000 --- a/arch/m32r/include/asm/module.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _ASM_M32R_MODULE_H -#define _ASM_M32R_MODULE_H - -struct mod_arch_specific { }; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - -#endif /* _ASM_M32R_MODULE_H */ diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c index 3071fe83ffc8..38233b6596b6 100644 --- a/arch/m32r/kernel/module.c +++ b/arch/m32r/kernel/module.c @@ -201,18 +201,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, } return 0; } - -int apply_relocate(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ -#if 0 - printk(KERN_ERR "module %s: REL RELOCATION unsupported\n", - me->name); - return -ENOEXEC; -#endif - return 0; - -} diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index b22df9410dce..0df07cee3faf 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -13,6 +13,9 @@ config M68K select FPU if MMU select ARCH_WANT_IPC_PARSE_VERSION select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_REL + select MODULES_USE_ELF_RELA config RWSEM_GENERIC_SPINLOCK bool diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h index edffe66b7f49..8b58fce843dd 100644 --- a/arch/m68k/include/asm/module.h +++ b/arch/m68k/include/asm/module.h @@ -1,6 +1,8 @@ #ifndef _ASM_M68K_MODULE_H #define _ASM_M68K_MODULE_H +#include + enum m68k_fixup_type { m68k_fixup_memoffset, m68k_fixup_vnode_shift, @@ -36,8 +38,4 @@ struct module; extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, struct m68k_fixup_info *end); -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr - #endif /* _ASM_M68K_MODULE_H */ diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index ab9afcaa7f6a..b4f409f942ab 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -24,6 +24,7 @@ config MICROBLAZE select GENERIC_CPU_DEVICES select GENERIC_ATOMIC64 select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA config SWAP def_bool n diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index faf65286574e..dccdfcd9e18e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -36,6 +36,9 @@ config MIPS select BUILDTIME_EXTABLE_SORT select GENERIC_CLOCKEVENTS select GENERIC_CMOS_UPDATE + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_REL + select MODULES_USE_ELF_RELA if 64BIT menu "Machine selection" diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index dca8bce8c7ab..26137da1c713 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -35,11 +35,14 @@ typedef struct { } Elf64_Mips_Rela; #ifdef CONFIG_32BIT - #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr #define Elf_Addr Elf32_Addr +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define ELF_R_TYPE(X) ELF32_R_TYPE(X) +#define ELF_R_SYM(X) ELF32_R_SYM(X) #define Elf_Mips_Rel Elf32_Rel #define Elf_Mips_Rela Elf32_Rela @@ -50,11 +53,14 @@ typedef struct { #endif #ifdef CONFIG_64BIT - #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define Elf_Ehdr Elf64_Ehdr #define Elf_Addr Elf64_Addr +#define Elf_Rel Elf64_Rel +#define Elf_Rela Elf64_Rela +#define ELF_R_TYPE(X) ELF64_R_TYPE(X) +#define ELF_R_SYM(X) ELF64_R_SYM(X) #define Elf_Mips_Rel Elf64_Mips_Rel #define Elf_Mips_Rela Elf64_Mips_Rela diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index e2c14999839a..cd1e6c2421b2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -31,7 +31,7 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o -obj-$(CONFIG_MODULES) += module-rela.o +obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 5cfb086b3903..aa03f2e13385 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -8,6 +8,7 @@ config MN10300 select HAVE_ARCH_KGDB select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA config AM33_2 def_bool n diff --git a/arch/mn10300/include/asm/module.h b/arch/mn10300/include/asm/module.h index 5d7057d01494..6571103b0518 100644 --- a/arch/mn10300/include/asm/module.h +++ b/arch/mn10300/include/asm/module.h @@ -12,12 +12,7 @@ #ifndef _ASM_MODULE_H #define _ASM_MODULE_H -struct mod_arch_specific { -}; - -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#include /* * Include the MN10300 architecture version. diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 49765b53f637..05f2ba41ff1a 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -21,6 +21,7 @@ config OPENRISC select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select MODULES_USE_ELF_RELA config MMU def_bool y diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3ff21b536f28..166d9911bc83 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -19,6 +19,8 @@ config PARISC select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD select GENERIC_STRNCPY_FROM_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/parisc/include/asm/module.h b/arch/parisc/include/asm/module.h index 1f4123427ea0..bab37e99168a 100644 --- a/arch/parisc/include/asm/module.h +++ b/arch/parisc/include/asm/module.h @@ -1,21 +1,11 @@ #ifndef _ASM_PARISC_MODULE_H #define _ASM_PARISC_MODULE_H + +#include + /* * This file contains the parisc architecture specific module code. */ -#ifdef CONFIG_64BIT -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Addr Elf64_Addr -#define Elf_Rela Elf64_Rela -#else -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Addr Elf32_Addr -#define Elf_Rela Elf32_Rela -#endif struct unwind_table; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 352f416269ce..74f84781b484 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -139,6 +139,8 @@ config PPC select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA config EARLY_PRINTK bool diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index 0192a4ee2bc2..c1df590ec444 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h @@ -11,6 +11,7 @@ #include #include +#include #ifndef __powerpc64__ @@ -60,16 +61,10 @@ struct mod_arch_specific { */ #ifdef __powerpc64__ -# define Elf_Shdr Elf64_Shdr -# define Elf_Sym Elf64_Sym -# define Elf_Ehdr Elf64_Ehdr # ifdef MODULE asm(".section .stubs,\"ax\",@nobits; .align 3; .previous"); # endif #else -# define Elf_Shdr Elf32_Shdr -# define Elf_Sym Elf32_Sym -# define Elf_Ehdr Elf32_Ehdr # ifdef MODULE asm(".section .plt,\"ax\",@nobits; .align 3; .previous"); asm(".section .init.plt,\"ax\",@nobits; .align 3; .previous"); diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 107610e01a29..c76a052f60e2 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -125,6 +125,8 @@ config S390 select GENERIC_CLOCKEVENTS select KTIME_SCALAR if 32BIT select HAVE_ARCH_SECCOMP_FILTER + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_RELA config SCHED_OMIT_FRAME_POINTER def_bool y diff --git a/arch/s390/include/asm/module.h b/arch/s390/include/asm/module.h index f0b6b26b6e59..df1f861a848a 100644 --- a/arch/s390/include/asm/module.h +++ b/arch/s390/include/asm/module.h @@ -1,5 +1,8 @@ #ifndef _ASM_S390_MODULE_H #define _ASM_S390_MODULE_H + +#include + /* * This file contains the s390 architecture specific module code. */ @@ -28,19 +31,4 @@ struct mod_arch_specific struct mod_arch_syminfo *syminfo; }; -#ifdef CONFIG_64BIT -#define ElfW(x) Elf64_ ## x -#define ELFW(x) ELF64_ ## x -#else -#define ElfW(x) Elf32_ ## x -#define ELFW(x) ELF32_ ## x -#endif - -#define Elf_Addr ElfW(Addr) -#define Elf_Rela ElfW(Rela) -#define Elf_Shdr ElfW(Shdr) -#define Elf_Sym ElfW(Sym) -#define Elf_Ehdr ElfW(Ehdr) -#define ELF_R_SYM ELFW(R_SYM) -#define ELF_R_TYPE ELFW(R_TYPE) #endif /* _ASM_S390_MODULE_H */ diff --git a/arch/score/Kconfig b/arch/score/Kconfig index ba0f412920be..e2c8db4533dc 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -10,6 +10,8 @@ config SCORE select ARCH_DISCARD_MEMBLOCK select GENERIC_CPU_DEVICES select GENERIC_CLOCKEVENTS + select HAVE_MOD_ARCH_SPECIFIC + select MODULES_USE_ELF_REL choice prompt "System type" diff --git a/arch/score/include/asm/module.h b/arch/score/include/asm/module.h index f0b5dc0bd023..abf395bbfaba 100644 --- a/arch/score/include/asm/module.h +++ b/arch/score/include/asm/module.h @@ -3,6 +3,7 @@ #include #include +#include struct mod_arch_specific { /* Data Bus Error exception tables */ @@ -13,11 +14,6 @@ struct mod_arch_specific { typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr -#define Elf_Addr Elf32_Addr - /* Given an address, look for it in the exception tables. */ #ifdef CONFIG_MODULES const struct exception_table_entry *search_module_dbetables(unsigned long addr); diff --git a/arch/score/kernel/module.c b/arch/score/kernel/module.c index 469e3b64e2f2..1378d99baa3d 100644 --- a/arch/score/kernel/module.c +++ b/arch/score/kernel/module.c @@ -125,16 +125,6 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, return 0; } -int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, - struct module *me) -{ - /* Non-standard return value... most other arch's return -ENOEXEC - * for an unsupported relocation variant - */ - return 0; -} - /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_dbetables(unsigned long addr) { diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 36f5141e8041..656329a9a59b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -35,6 +35,8 @@ config SUPERH select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER + select MODULES_USE_ELF_RELA help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h index b7927de86f9f..81300d8b5448 100644 --- a/arch/sh/include/asm/module.h +++ b/arch/sh/include/asm/module.h @@ -1,21 +1,13 @@ #ifndef _ASM_SH_MODULE_H #define _ASM_SH_MODULE_H -struct mod_arch_specific { +#include + #ifdef CONFIG_DWARF_UNWINDER +struct mod_arch_specific { struct list_head fde_list; struct list_head cie_list; -#endif }; - -#ifdef CONFIG_64BIT -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr -#else -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr #endif #ifdef CONFIG_CPU_LITTLE_ENDIAN diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 67f1f6f5f4e1..a244e70b9bb0 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -37,6 +37,7 @@ config SPARC select GENERIC_CLOCKEVENTS select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select MODULES_USE_ELF_RELA config SPARC32 def_bool !64BIT diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 67f83e0a0d68..fbe1cb578fcd 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -21,4 +21,5 @@ generic-y += div64.h generic-y += local64.h generic-y += irq_regs.h generic-y += local.h +generic-y += module.h generic-y += word-at-a-time.h diff --git a/arch/sparc/include/asm/module.h b/arch/sparc/include/asm/module.h deleted file mode 100644 index ff8e02d80334..000000000000 --- a/arch/sparc/include/asm/module.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __SPARC_MODULE_H -#define __SPARC_MODULE_H -struct mod_arch_specific { }; - -/* - * Use some preprocessor magic to define the correct symbol - * for sparc32 and sparc64. - * Elf_Addr becomes Elf32_Addr for sparc32 and Elf64_Addr for sparc64 - */ -#define ___ELF(a, b, c) a##b##c -#define __ELF(a, b, c) ___ELF(a, b, c) -#define _Elf(t) __ELF(Elf, CONFIG_BITS, t) -#define _ELF(t) __ELF(ELF, CONFIG_BITS, t) - -#define Elf_Shdr _Elf(_Shdr) -#define Elf_Sym _Elf(_Sym) -#define Elf_Ehdr _Elf(_Ehdr) -#define Elf_Rela _Elf(_Rela) -#define Elf_Addr _Elf(_Addr) - -#define ELF_R_SYM _ELF(_R_SYM) -#define ELF_R_TYPE _ELF(_R_TYPE) - -#endif /* __SPARC_MODULE_H */ diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 932e4430f7f3..1603f3043399 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -17,6 +17,7 @@ config TILE select SYS_HYPERVISOR select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_CLOCKEVENTS + select MODULES_USE_ELF_RELA # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index b0a47433341e..5ef081475bba 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -14,6 +14,7 @@ config UNICORE32 select GENERIC_IRQ_SHOW select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP + select MODULES_USE_ELF_REL help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8ec3a1aa4abd..01726cbcc73b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -97,6 +97,8 @@ config X86 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select MODULES_USE_ELF_REL if X86_32 + select MODULES_USE_ELF_RELA if X86_64 config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS || UPROBES) diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig index 9926e11a772d..a4b0c10c9d5d 100644 --- a/arch/x86/um/Kconfig +++ b/arch/x86/um/Kconfig @@ -21,9 +21,11 @@ config 64BIT config X86_32 def_bool !64BIT select HAVE_AOUT + select MODULES_USE_ELF_REL config X86_64 def_bool 64BIT + select MODULES_USE_ELF_RELA config RWSEM_XCHGADD_ALGORITHM def_bool X86_XADD && 64BIT diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8ed64cfae4ff..4816e44001f1 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -11,6 +11,7 @@ config XTENSA select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES + select MODULES_USE_ELF_RELA help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both diff --git a/arch/xtensa/include/asm/module.h b/arch/xtensa/include/asm/module.h index d9b34bee4d42..488b40c6f9b9 100644 --- a/arch/xtensa/include/asm/module.h +++ b/arch/xtensa/include/asm/module.h @@ -13,15 +13,8 @@ #ifndef _XTENSA_MODULE_H #define _XTENSA_MODULE_H -struct mod_arch_specific -{ - /* No special elements, yet. */ -}; - #define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " " -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#include #endif /* _XTENSA_MODULE_H */ diff --git a/include/asm-generic/module.h b/include/asm-generic/module.h index ed5b44de4c91..14dc41d185a7 100644 --- a/include/asm-generic/module.h +++ b/include/asm-generic/module.h @@ -5,18 +5,44 @@ * Many architectures just need a simple module * loader without arch specific data. */ +#ifndef CONFIG_HAVE_MOD_ARCH_SPECIFIC struct mod_arch_specific { }; +#endif #ifdef CONFIG_64BIT -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define Elf_Ehdr Elf64_Ehdr -#else -#define Elf_Shdr Elf32_Shdr -#define Elf_Sym Elf32_Sym -#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Phdr Elf64_Phdr +#define Elf_Sym Elf64_Sym +#define Elf_Dyn Elf64_Dyn +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Addr Elf64_Addr +#ifdef CONFIG_MODULES_USE_ELF_REL +#define Elf_Rel Elf64_Rel +#endif +#ifdef CONFIG_MODULES_USE_ELF_RELA +#define Elf_Rela Elf64_Rela +#endif +#define ELF_R_TYPE(X) ELF64_R_TYPE(X) +#define ELF_R_SYM(X) ELF64_R_SYM(X) + +#else /* CONFIG_64BIT */ + +#define Elf_Shdr Elf32_Shdr +#define Elf_Phdr Elf32_Phdr +#define Elf_Sym Elf32_Sym +#define Elf_Dyn Elf32_Dyn +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Addr Elf32_Addr +#ifdef CONFIG_MODULES_USE_ELF_REL +#define Elf_Rel Elf32_Rel +#endif +#ifdef CONFIG_MODULES_USE_ELF_RELA +#define Elf_Rela Elf32_Rela +#endif +#define ELF_R_TYPE(X) ELF32_R_TYPE(X) +#define ELF_R_SYM(X) ELF32_R_SYM(X) #endif #endif /* __ASM_GENERIC_MODULE_H */ diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index b2be02ebf453..560ca53a75fa 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -28,21 +28,49 @@ void *module_alloc(unsigned long size); /* Free memory returned from module_alloc. */ void module_free(struct module *mod, void *module_region); -/* Apply the given relocation to the (simplified) ELF. Return -error - or 0. */ +/* + * Apply the given relocation to the (simplified) ELF. Return -error + * or 0. + */ +#ifdef CONFIG_MODULES_USE_ELF_REL int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *mod); +#else +static inline int apply_relocate(Elf_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); + return -ENOEXEC; +} +#endif -/* Apply the given add relocation to the (simplified) ELF. Return - -error or 0 */ +/* + * Apply the given add relocation to the (simplified) ELF. Return + * -error or 0 + */ +#ifdef CONFIG_MODULES_USE_ELF_RELA int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *mod); +#else +static inline int apply_relocate_add(Elf_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); + return -ENOEXEC; +} +#endif /* Any final processing of module before access. Return -error or 0. */ int module_finalize(const Elf_Ehdr *hdr, diff --git a/kernel/module.c b/kernel/module.c index 9ad9ee9406d6..7f2ee45f362c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1949,26 +1949,6 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) return ret; } -int __weak apply_relocate(Elf_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - pr_err("module %s: REL relocation unsupported\n", me->name); - return -ENOEXEC; -} - -int __weak apply_relocate_add(Elf_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - pr_err("module %s: RELA relocation unsupported\n", me->name); - return -ENOEXEC; -} - static int apply_relocations(struct module *mod, const struct load_info *info) { unsigned int i; -- cgit v1.2.3 From 6f13909f4fe9652f189b462c6c98767309000321 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 28 Sep 2012 14:31:03 +0930 Subject: module: fix symbol waiting when module fails before init We use resolve_symbol_wait(), which blocks if the module containing the symbol is still loading. However: 1) The module_wq we use is only woken after calling the modules' init function, but there are other failure paths after the module is placed in the linked list where we need to do the same thing. 2) wake_up() only wakes one waiter, and our waitqueue is shared by all modules, so we need to wake them all. 3) wake_up_all() doesn't imply a memory barrier: I feel happier calling it after we've grabbed and dropped the module_mutex, not just after the state assignment. Signed-off-by: Rusty Russell --- kernel/module.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 7f2ee45f362c..63cf6e7f1394 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2959,7 +2959,7 @@ static struct module *load_module(void __user *umod, /* Unlink carefully: kallsyms could be walking list. */ list_del_rcu(&mod->list); module_bug_cleanup(mod); - + wake_up_all(&module_wq); ddebug: dynamic_debug_remove(info.debug); unlock: @@ -3034,7 +3034,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); free_module(mod); - wake_up(&module_wq); + wake_up_all(&module_wq); return ret; } if (ret > 0) { @@ -3046,9 +3046,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, dump_stack(); } - /* Now it's a first class citizen! Wake up anyone waiting for it. */ + /* Now it's a first class citizen! */ mod->state = MODULE_STATE_LIVE; - wake_up(&module_wq); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_LIVE, mod); @@ -3071,6 +3070,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, mod->init_ro_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); + wake_up_all(&module_wq); return 0; } -- cgit v1.2.3 From 9bb9c3be56834653878f766f471fa1c20e562f4c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 28 Sep 2012 14:31:03 +0930 Subject: module: wait when loading a module which is currently initializing. The original module-init-tools module loader used a fnctl lock on the .ko file to avoid attempts to simultaneously load a module. Unfortunately, you can't get an exclusive fcntl lock on a read-only fd, making this not work for read-only mounted filesystems. module-init-tools has a hacky sleep-and-loop for this now. It's not that hard to wait in the kernel, and only return -EEXIST once the first module has finished loading (or continue loading the module if the first one failed to initialize for some reason). It's also consistent with what we do for dependent modules which are still loading. Suggested-by: Lucas De Marchi Signed-off-by: Rusty Russell --- kernel/module.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 63cf6e7f1394..74bc19562ca3 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2845,6 +2845,20 @@ static int post_relocation(struct module *mod, const struct load_info *info) return module_finalize(info->hdr, info->sechdrs, mod); } +/* Is this module of this name done loading? No locks held. */ +static bool finished_loading(const char *name) +{ + struct module *mod; + bool ret; + + mutex_lock(&module_mutex); + mod = find_module(name); + ret = !mod || mod->state != MODULE_STATE_COMING; + mutex_unlock(&module_mutex); + + return ret; +} + /* Allocate and load the module: note that size of section 0 is always zero, and we rely on this for optional sections. */ static struct module *load_module(void __user *umod, @@ -2852,7 +2866,7 @@ static struct module *load_module(void __user *umod, const char __user *uargs) { struct load_info info = { NULL, }; - struct module *mod; + struct module *mod, *old; long err; pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", @@ -2918,8 +2932,18 @@ static struct module *load_module(void __user *umod, * function to insert in a way safe to concurrent readers. * The mutex protects against concurrent writers. */ +again: mutex_lock(&module_mutex); - if (find_module(mod->name)) { + if ((old = find_module(mod->name)) != NULL) { + if (old->state == MODULE_STATE_COMING) { + /* Wait in case it fails to load. */ + mutex_unlock(&module_mutex); + err = wait_event_interruptible(module_wq, + finished_loading(mod->name)); + if (err) + goto free_arch_cleanup; + goto again; + } err = -EEXIST; goto unlock; } -- cgit v1.2.3 From cf7f601c067994f371ba77721d1e45fce61a4569 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 13 Sep 2012 13:06:29 +0100 Subject: KEYS: Add payload preparsing opportunity prior to key instantiate or update Give the key type the opportunity to preparse the payload prior to the instantiation and update routines being called. This is done with the provision of two new key type operations: int (*preparse)(struct key_preparsed_payload *prep); void (*free_preparse)(struct key_preparsed_payload *prep); If the first operation is present, then it is called before key creation (in the add/update case) or before the key semaphore is taken (in the update and instantiate cases). The second operation is called to clean up if the first was called. preparse() is given the opportunity to fill in the following structure: struct key_preparsed_payload { char *description; void *type_data[2]; void *payload; const void *data; size_t datalen; size_t quotalen; }; Before the preparser is called, the first three fields will have been cleared, the payload pointer and size will be stored in data and datalen and the default quota size from the key_type struct will be stored into quotalen. The preparser may parse the payload in any way it likes and may store data in the type_data[] and payload fields for use by the instantiate() and update() ops. The preparser may also propose a description for the key by attaching it as a string to the description field. This can be used by passing a NULL or "" description to the add_key() system call or the key_create_or_update() function. This cannot work with request_key() as that required the description to tell the upcall about the key to be created. This, for example permits keys that store PGP public keys to generate their own name from the user ID and public key fingerprint in the key. The instantiate() and update() operations are then modified to look like this: int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); int (*update)(struct key *key, struct key_preparsed_payload *prep); and the new payload data is passed in *prep, whether or not it was preparsed. Signed-off-by: David Howells Signed-off-by: Rusty Russell --- Documentation/security/keys.txt | 50 +++++++++++++- fs/cifs/cifs_spnego.c | 6 +- fs/cifs/cifsacl.c | 8 +-- include/keys/user-type.h | 6 +- include/linux/key-type.h | 35 +++++++++- net/ceph/crypto.c | 9 +-- net/dns_resolver/dns_key.c | 6 +- net/rxrpc/ar-key.c | 40 +++++------ security/keys/encrypted-keys/encrypted.c | 16 +++-- security/keys/key.c | 114 ++++++++++++++++++++++--------- security/keys/keyctl.c | 18 +++-- security/keys/keyring.c | 6 +- security/keys/request_key_auth.c | 8 +-- security/keys/trusted.c | 16 +++-- security/keys/user_defined.c | 14 ++-- 15 files changed, 250 insertions(+), 102 deletions(-) diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt index aa0dbd74b71b..7d9ca92022d8 100644 --- a/Documentation/security/keys.txt +++ b/Documentation/security/keys.txt @@ -412,6 +412,10 @@ The main syscalls are: to the keyring. In this case, an error will be generated if the process does not have permission to write to the keyring. + If the key type supports it, if the description is NULL or an empty + string, the key type will try and generate a description from the content + of the payload. + The payload is optional, and the pointer can be NULL if not required by the type. The payload is plen in size, and plen can be zero for an empty payload. @@ -1114,12 +1118,53 @@ The structure has a number of fields, some of which are mandatory: it should return 0. - (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); + (*) int (*preparse)(struct key_preparsed_payload *prep); + + This optional method permits the key type to attempt to parse payload + before a key is created (add key) or the key semaphore is taken (update or + instantiate key). The structure pointed to by prep looks like: + + struct key_preparsed_payload { + char *description; + void *type_data[2]; + void *payload; + const void *data; + size_t datalen; + size_t quotalen; + }; + + Before calling the method, the caller will fill in data and datalen with + the payload blob parameters; quotalen will be filled in with the default + quota size from the key type and the rest will be cleared. + + If a description can be proposed from the payload contents, that should be + attached as a string to the description field. This will be used for the + key description if the caller of add_key() passes NULL or "". + + The method can attach anything it likes to type_data[] and payload. These + are merely passed along to the instantiate() or update() operations. + + The method should return 0 if success ful or a negative error code + otherwise. + + + (*) void (*free_preparse)(struct key_preparsed_payload *prep); + + This method is only required if the preparse() method is provided, + otherwise it is unused. It cleans up anything attached to the + description, type_data and payload fields of the key_preparsed_payload + struct as filled in by the preparse() method. + + + (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); This method is called to attach a payload to a key during construction. The payload attached need not bear any relation to the data passed to this function. + The prep->data and prep->datalen fields will define the original payload + blob. If preparse() was supplied then other fields may be filled in also. + If the amount of data attached to the key differs from the size in keytype->def_datalen, then key_payload_reserve() should be called. @@ -1135,6 +1180,9 @@ The structure has a number of fields, some of which are mandatory: If this type of key can be updated, then this method should be provided. It is called to update a key's payload from the blob of data provided. + The prep->data and prep->datalen fields will define the original payload + blob. If preparse() was supplied then other fields may be filled in also. + key_payload_reserve() should be called if the data length might change before any changes are actually made. Note that if this succeeds, the type is committed to changing the key because it's already been altered, so all diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index e622863b292f..086f381d6489 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c @@ -31,18 +31,18 @@ /* create a new cifs key */ static int -cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) +cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; int ret; ret = -ENOMEM; - payload = kmalloc(datalen, GFP_KERNEL); + payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) goto error; /* attach the data */ - memcpy(payload, data, datalen); + memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; ret = 0; diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 05f4dc263a23..f3c60e264ca8 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -167,17 +167,17 @@ static struct shrinker cifs_shrinker = { }; static int -cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) +cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { char *payload; - payload = kmalloc(datalen, GFP_KERNEL); + payload = kmalloc(prep->datalen, GFP_KERNEL); if (!payload) return -ENOMEM; - memcpy(payload, data, datalen); + memcpy(payload, prep->data, prep->datalen); key->payload.data = payload; - key->datalen = datalen; + key->datalen = prep->datalen; return 0; } diff --git a/include/keys/user-type.h b/include/keys/user-type.h index bc9ec1d7698c..5e452c84f1e6 100644 --- a/include/keys/user-type.h +++ b/include/keys/user-type.h @@ -35,8 +35,10 @@ struct user_key_payload { extern struct key_type key_type_user; extern struct key_type key_type_logon; -extern int user_instantiate(struct key *key, const void *data, size_t datalen); -extern int user_update(struct key *key, const void *data, size_t datalen); +struct key_preparsed_payload; + +extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); +extern int user_update(struct key *key, struct key_preparsed_payload *prep); extern int user_match(const struct key *key, const void *criterion); extern void user_revoke(struct key *key); extern void user_destroy(struct key *key); diff --git a/include/linux/key-type.h b/include/linux/key-type.h index f0c651cda7b0..518a53afb9ea 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -26,6 +26,27 @@ struct key_construction { struct key *authkey;/* authorisation for key being constructed */ }; +/* + * Pre-parsed payload, used by key add, update and instantiate. + * + * This struct will be cleared and data and datalen will be set with the data + * and length parameters from the caller and quotalen will be set from + * def_datalen from the key type. Then if the preparse() op is provided by the + * key type, that will be called. Then the struct will be passed to the + * instantiate() or the update() op. + * + * If the preparse() op is given, the free_preparse() op will be called to + * clear the contents. + */ +struct key_preparsed_payload { + char *description; /* Proposed key description (or NULL) */ + void *type_data[2]; /* Private key-type data */ + void *payload; /* Proposed payload */ + const void *data; /* Raw data */ + size_t datalen; /* Raw datalen */ + size_t quotalen; /* Quota length for proposed payload */ +}; + typedef int (*request_key_actor_t)(struct key_construction *key, const char *op, void *aux); @@ -45,18 +66,28 @@ struct key_type { /* vet a description */ int (*vet_description)(const char *description); + /* Preparse the data blob from userspace that is to be the payload, + * generating a proposed description and payload that will be handed to + * the instantiate() and update() ops. + */ + int (*preparse)(struct key_preparsed_payload *prep); + + /* Free a preparse data structure. + */ + void (*free_preparse)(struct key_preparsed_payload *prep); + /* instantiate a key of this type * - this method should call key_payload_reserve() to determine if the * user's quota will hold the payload */ - int (*instantiate)(struct key *key, const void *data, size_t datalen); + int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); /* update a key of this type (optional) * - this method should call key_payload_reserve() to recalculate the * quota consumption * - the key must be locked against read when modifying */ - int (*update)(struct key *key, const void *data, size_t datalen); + int (*update)(struct key *key, struct key_preparsed_payload *prep); /* match a key against a description */ int (*match)(const struct key *key, const void *desc); diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 9da7fdd3cd8a..af14cb425164 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -423,14 +423,15 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, } } -int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) +int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep) { struct ceph_crypto_key *ckey; + size_t datalen = prep->datalen; int ret; void *p; ret = -EINVAL; - if (datalen <= 0 || datalen > 32767 || !data) + if (datalen <= 0 || datalen > 32767 || !prep->data) goto err; ret = key_payload_reserve(key, datalen); @@ -443,8 +444,8 @@ int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) goto err; /* TODO ceph_crypto_key_decode should really take const input */ - p = (void *)data; - ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); + p =