diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-19 10:55:08 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-19 10:55:08 -0500 |
| commit | 7a684c452e2589f3ddd7e2d466b4f747d3715ad9 (patch) | |
| tree | fed803e7450770993575b37807ba2195eafd5b0e /kernel | |
| parent | 7f2de8171ddf28fdb2ca7f9a683ee1207849f718 (diff) | |
| parent | e10e1774efbdaec54698454200619a03a01e1d64 (diff) | |
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module update from Rusty Russell:
"Nothing all that exciting; a new module-from-fd syscall for those who
want to verify the source of the module (ChromeOS) and/or use standard
IMA on it or other security hooks."
* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
MODSIGN: Fix kbuild output when using default extra_certificates
MODSIGN: Avoid using .incbin in C source
modules: don't hand 0 to vmalloc.
module: Remove a extra null character at the top of module->strtab.
ASN.1: Use the ASN1_LONG_TAG and ASN1_INDEFINITE_LENGTH constants
ASN.1: Define indefinite length marker constant
moduleparam: use __UNIQUE_ID()
__UNIQUE_ID()
MODSIGN: Add modules_sign make target
powerpc: add finit_module syscall.
ima: support new kernel module syscall
add finit_module syscall to asm-generic
ARM: add finit_module syscall to ARM
security: introduce kernel_module_from_file hook
module: add flags arg to sys_finit_module()
module: add syscall to load module from fd
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/Makefile | 10 | ||||
| -rw-r--r-- | kernel/modsign_certificate.S | 19 | ||||
| -rw-r--r-- | kernel/modsign_pubkey.c | 6 | ||||
| -rw-r--r-- | kernel/module.c | 441 | ||||
| -rw-r--r-- | kernel/sys_ni.c | 1 |
5 files changed, 294 insertions, 183 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index ac0d533eb7d..6c072b6da23 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
| @@ -54,7 +54,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o | |||
| 54 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o | 54 | obj-$(CONFIG_PROVE_LOCKING) += spinlock.o |
| 55 | obj-$(CONFIG_UID16) += uid16.o | 55 | obj-$(CONFIG_UID16) += uid16.o |
| 56 | obj-$(CONFIG_MODULES) += module.o | 56 | obj-$(CONFIG_MODULES) += module.o |
| 57 | obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o | 57 | obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o |
| 58 | obj-$(CONFIG_KALLSYMS) += kallsyms.o | 58 | obj-$(CONFIG_KALLSYMS) += kallsyms.o |
| 59 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o | 59 | obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o |
| 60 | obj-$(CONFIG_KEXEC) += kexec.o | 60 | obj-$(CONFIG_KEXEC) += kexec.o |
| @@ -137,10 +137,14 @@ ifeq ($(CONFIG_MODULE_SIG),y) | |||
| 137 | # | 137 | # |
| 138 | # Pull the signing certificate and any extra certificates into the kernel | 138 | # Pull the signing certificate and any extra certificates into the kernel |
| 139 | # | 139 | # |
| 140 | |||
| 141 | quiet_cmd_touch = TOUCH $@ | ||
| 142 | cmd_touch = touch $@ | ||
| 143 | |||
| 140 | extra_certificates: | 144 | extra_certificates: |
| 141 | touch $@ | 145 | $(call cmd,touch) |
| 142 | 146 | ||
| 143 | kernel/modsign_pubkey.o: signing_key.x509 extra_certificates | 147 | kernel/modsign_certificate.o: signing_key.x509 extra_certificates |
| 144 | 148 | ||
| 145 | ############################################################################### | 149 | ############################################################################### |
| 146 | # | 150 | # |
diff --git a/kernel/modsign_certificate.S b/kernel/modsign_certificate.S new file mode 100644 index 00000000000..246b4c6e613 --- /dev/null +++ b/kernel/modsign_certificate.S | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */ | ||
| 2 | #ifndef SYMBOL_PREFIX | ||
| 3 | #define ASM_SYMBOL(sym) sym | ||
| 4 | #else | ||
| 5 | #define PASTE2(x,y) x##y | ||
| 6 | #define PASTE(x,y) PASTE2(x,y) | ||
| 7 | #define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #define GLOBAL(name) \ | ||
| 11 | .globl ASM_SYMBOL(name); \ | ||
| 12 | ASM_SYMBOL(name): | ||
| 13 | |||
| 14 | .section ".init.data","aw" | ||
| 15 | |||
| 16 | GLOBAL(modsign_certificate_list) | ||
| 17 | .incbin "signing_key.x509" | ||
| 18 | .incbin "extra_certificates" | ||
| 19 | GLOBAL(modsign_certificate_list_end) | ||
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c index 767e559dfb1..045504fffbb 100644 --- a/kernel/modsign_pubkey.c +++ b/kernel/modsign_pubkey.c | |||
| @@ -20,12 +20,6 @@ struct key *modsign_keyring; | |||
| 20 | 20 | ||
| 21 | extern __initdata const u8 modsign_certificate_list[]; | 21 | extern __initdata const u8 modsign_certificate_list[]; |
| 22 | extern __initdata const u8 modsign_certificate_list_end[]; | 22 | extern __initdata const u8 modsign_certificate_list_end[]; |
| 23 | asm(".section .init.data,\"aw\"\n" | ||
| 24 | SYMBOL_PREFIX "modsign_certificate_list:\n" | ||
| 25 | ".incbin \"signing_key.x509\"\n" | ||
| 26 | ".incbin \"extra_certificates\"\n" | ||
| 27 | SYMBOL_PREFIX "modsign_certificate_list_end:" | ||
| 28 | ); | ||
| 29 | 23 | ||
| 30 | /* | 24 | /* |
| 31 | * We need to make sure ccache doesn't cache the .o file as it doesn't notice | 25 | * We need to make sure ccache doesn't cache the .o file as it doesn't notice |
diff --git a/kernel/module.c b/kernel/module.c index 808bd62e172..250092c1d57 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/ftrace_event.h> | 21 | #include <linux/ftrace_event.h> |
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/kallsyms.h> | 23 | #include <linux/kallsyms.h> |
| 24 | #include <linux/file.h> | ||
| 24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 25 | #include <linux/sysfs.h> | 26 | #include <linux/sysfs.h> |
| 26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| @@ -28,6 +29,7 @@ | |||
| 28 | #include <linux/vmalloc.h> | 29 | #include <linux/vmalloc.h> |
| 29 | #include <linux/elf.h> | 30 | #include <linux/elf.h> |
| 30 | #include <linux/proc_fs.h> | 31 | #include <linux/proc_fs.h> |
| 32 | #include <linux/security.h> | ||
| 31 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
| 32 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
| 33 | #include <linux/fcntl.h> | 35 | #include <linux/fcntl.h> |
| @@ -59,6 +61,7 @@ | |||
| 59 | #include <linux/pfn.h> | 61 | #include <linux/pfn.h> |
| 60 | #include <linux/bsearch.h> | 62 | #include <linux/bsearch.h> |
| 61 | #include <linux/fips.h> | 63 | #include <linux/fips.h> |
| 64 | #include <uapi/linux/module.h> | ||
| 62 | #include "module-internal.h" | 65 | #include "module-internal.h" |
| 63 | 66 | ||
| 64 | #define CREATE_TRACE_POINTS | 67 | #define CREATE_TRACE_POINTS |
| @@ -2279,7 +2282,7 @@ static void layout_symtab(struct module *mod, struct load_info *info) | |||
| 2279 | Elf_Shdr *symsect = info->sechdrs + info->index.sym; | 2282 | Elf_Shdr *symsect = info->sechdrs + info->index.sym; |
| 2280 | Elf_Shdr *strsect = info->sechdrs + info->index.str; | 2283 | Elf_Shdr *strsect = info->sechdrs + info->index.str; |
| 2281 | const Elf_Sym *src; | 2284 | const Elf_Sym *src; |
| 2282 | unsigned int i, nsrc, ndst, strtab_size; | 2285 | unsigned int i, nsrc, ndst, strtab_size = 0; |
| 2283 | 2286 | ||
| 2284 | /* Put symbol section at end of init part of module. */ | 2287 | /* Put symbol section at end of init part of module. */ |
| 2285 | symsect->sh_flags |= SHF_ALLOC; | 2288 | symsect->sh_flags |= SHF_ALLOC; |
| @@ -2290,9 +2293,6 @@ static void layout_symtab(struct module *mod, struct load_info *info) | |||
| 2290 | src = (void *)info->hdr + symsect->sh_offset; | 2293 | src = (void *)info->hdr + symsect->sh_offset; |
| 2291 | nsrc = symsect->sh_size / sizeof(*src); | 2294 | nsrc = symsect->sh_size / sizeof(*src); |
| 2292 | 2295 | ||
| 2293 | /* strtab always starts with a nul, so offset 0 is the empty string. */ | ||
| 2294 | strtab_size = 1; | ||
| 2295 | |||
| 2296 | /* Compute total space required for the core symbols' strtab. */ | 2296 | /* Compute total space required for the core symbols' strtab. */ |
| 2297 | for (ndst = i = 0; i < nsrc; i++) { | 2297 | for (ndst = i = 0; i < nsrc; i++) { |
| 2298 | if (i == 0 || | 2298 | if (i == 0 || |
| @@ -2334,7 +2334,6 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) | |||
| 2334 | mod->core_symtab = dst = mod->module_core + info->symoffs; | 2334 | mod->core_symtab = dst = mod->module_core + info->symoffs; |
| 2335 | mod->core_strtab = s = mod->module_core + info->stroffs; | 2335 | mod->core_strtab = s = mod->module_core + info->stroffs; |
| 2336 | src = mod->symtab; | 2336 | src = mod->symtab; |
| 2337 | *s++ = 0; | ||
| 2338 | for (ndst = i = 0; i < mod->num_symtab; i++) { | 2337 | for (ndst = i = 0; i < mod->num_symtab; i++) { |
| 2339 | if (i == 0 || | 2338 | if (i == 0 || |
| 2340 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { | 2339 | is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { |
| @@ -2375,7 +2374,7 @@ static void dynamic_debug_remove(struct _ddebug *debug) | |||
| 2375 | 2374 | ||
| 2376 | void * __weak module_alloc(unsigned long size) | 2375 | void * __weak module_alloc(unsigned long size) |
| 2377 | { | 2376 | { |
| 2378 | return size == 0 ? NULL : vmalloc_exec(size); | 2377 | return vmalloc_exec(size); |
| 2379 | } | 2378 | } |
| 2380 | 2379 | ||
| 2381 | static void *module_alloc_update_bounds(unsigned long size) | 2380 | static void *module_alloc_update_bounds(unsigned long size) |
| @@ -2422,18 +2421,17 @@ static inline void kmemleak_load_module(const struct module *mod, | |||
| 2422 | #endif | 2421 | #endif |
| 2423 | 2422 | ||
| 2424 | #ifdef CONFIG_MODULE_SIG | 2423 | #ifdef CONFIG_MODULE_SIG |
| 2425 | static int module_sig_check(struct load_info *info, | 2424 | static int module_sig_check(struct load_info *info) |
| 2426 | const void *mod, unsigned long *_len) | ||
| 2427 | { | 2425 | { |
| 2428 | int err = -ENOKEY; | 2426 | int err = -ENOKEY; |
| 2429 | unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; | 2427 | const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; |
| 2430 | unsigned long len = *_len; | 2428 | const void *mod = info->hdr; |
| 2431 | 2429 | ||
| 2432 | if (len > markerlen && | 2430 | if (info->len > markerlen && |
| 2433 | memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { | 2431 | memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { |
| 2434 | /* We truncate the module to discard the signature */ | 2432 | /* We truncate the module to discard the signature */ |
| 2435 | *_len -= markerlen; | 2433 | info->len -= markerlen; |
| 2436 | err = mod_verify_sig(mod, _len); | 2434 | err = mod_verify_sig(mod, &info->len); |
| 2437 | } | 2435 | } |
| 2438 | 2436 | ||
| 2439 | if (!err) { | 2437 | if (!err) { |
| @@ -2451,59 +2449,107 @@ static int module_sig_check(struct load_info *info, | |||
| 2451 | return err; | 2449 | return err; |
| 2452 | } | 2450 | } |
| 2453 | #else /* !CONFIG_MODULE_SIG */ | 2451 | #else /* !CONFIG_MODULE_SIG */ |
| 2454 | static int module_sig_check(struct load_info *info, | 2452 | static int module_sig_check(struct load_info *info) |
| 2455 | void *mod, unsigned long *len) | ||
| 2456 | { | 2453 | { |
| 2457 | return 0; | 2454 | return 0; |
| 2458 | } | 2455 | } |
| 2459 | #endif /* !CONFIG_MODULE_SIG */ | 2456 | #endif /* !CONFIG_MODULE_SIG */ |
| 2460 | 2457 | ||
| 2461 | /* Sets info->hdr, info->len and info->sig_ok. */ | 2458 | /* Sanity checks against invalid binaries, wrong arch, weird elf version. */ |
| 2462 | static int copy_and_check(struct load_info *info, | 2459 | static int elf_header_check(struct load_info *info) |
| 2463 | const void __user *umod, unsigned long len, | 2460 | { |
| 2464 | const char __user *uargs) | 2461 | if (info->len < sizeof(*(info->hdr))) |
| 2462 | return -ENOEXEC; | ||
| 2463 | |||
| 2464 | if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0 | ||
| 2465 | || info->hdr->e_type != ET_REL | ||
