aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-19 10:55:08 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-19 10:55:08 -0500
commit7a684c452e2589f3ddd7e2d466b4f747d3715ad9 (patch)
treefed803e7450770993575b37807ba2195eafd5b0e /kernel
parent7f2de8171ddf28fdb2ca7f9a683ee1207849f718 (diff)
parente10e1774efbdaec54698454200619a03a01e1d64 (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/Makefile10
-rw-r--r--kernel/modsign_certificate.S19
-rw-r--r--kernel/modsign_pubkey.c6
-rw-r--r--kernel/module.c441
-rw-r--r--kernel/sys_ni.c1
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
54obj-$(CONFIG_PROVE_LOCKING) += spinlock.o 54obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
55obj-$(CONFIG_UID16) += uid16.o 55obj-$(CONFIG_UID16) += uid16.o
56obj-$(CONFIG_MODULES) += module.o 56obj-$(CONFIG_MODULES) += module.o
57obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o 57obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
58obj-$(CONFIG_KALLSYMS) += kallsyms.o 58obj-$(CONFIG_KALLSYMS) += kallsyms.o
59obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 59obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
60obj-$(CONFIG_KEXEC) += kexec.o 60obj-$(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
141quiet_cmd_touch = TOUCH $@
142 cmd_touch = touch $@
143
140extra_certificates: 144extra_certificates:
141 touch $@ 145 $(call cmd,touch)
142 146
143kernel/modsign_pubkey.o: signing_key.x509 extra_certificates 147kernel/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
16GLOBAL(modsign_certificate_list)
17 .incbin "signing_key.x509"
18 .incbin "extra_certificates"
19GLOBAL(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
21extern __initdata const u8 modsign_certificate_list[]; 21extern __initdata const u8 modsign_certificate_list[];
22extern __initdata const u8 modsign_certificate_list_end[]; 22extern __initdata const u8 modsign_certificate_list_end[];
23asm(".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
2376void * __weak module_alloc(unsigned long size) 2375void * __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
2381static void *module_alloc_update_bounds(unsigned long size) 2380static 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
2425static int module_sig_check(struct load_info *info, 2424static 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 */
2454static int module_sig_check(struct load_info *info, 2452static 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. */
2462static int copy_and_check(struct load_info *info, 2459static 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