aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--Documentation/ABI/testing/ima_policy3
-rw-r--r--Makefile6
-rw-r--r--arch/arm/include/uapi/asm/unistd.h1
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/cris/kernel/module.c2
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/powerpc/include/asm/systbl.h1
-rw-r--r--arch/powerpc/include/asm/unistd.h2
-rw-r--r--arch/powerpc/include/uapi/asm/unistd.h1
-rw-r--r--arch/sparc/kernel/module.c4
-rw-r--r--arch/tile/kernel/module.c2
-rw-r--r--arch/unicore32/kernel/module.c3
-rw-r--r--arch/x86/syscalls/syscall_32.tbl1
-rw-r--r--arch/x86/syscalls/syscall_64.tbl1
-rw-r--r--include/linux/asn1.h2
-rw-r--r--include/linux/compiler-gcc4.h2
-rw-r--r--include/linux/compiler.h9
-rw-r--r--include/linux/ima.h6
-rw-r--r--include/linux/moduleparam.h6
-rw-r--r--include/linux/security.h13
-rw-r--r--include/linux/syscalls.h1
-rw-r--r--include/uapi/asm-generic/unistd.h4
-rw-r--r--include/uapi/linux/module.h8
-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
-rw-r--r--lib/asn1_decoder.c8
-rw-r--r--scripts/Makefile.modsign32
-rw-r--r--security/capability.c6
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_api.c4
-rw-r--r--security/integrity/ima/ima_main.c21
-rw-r--r--security/integrity/ima/ima_policy.c3
-rw-r--r--security/security.c10
36 files changed, 434 insertions, 210 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 986946613542..ec0a38ef3145 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -23,7 +23,7 @@ Description:
23 lsm: [[subj_user=] [subj_role=] [subj_type=] 23 lsm: [[subj_user=] [subj_role=] [subj_type=]
24 [obj_user=] [obj_role=] [obj_type=]] 24 [obj_user=] [obj_role=] [obj_type=]]
25 25
26 base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK] 26 base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK][MODULE_CHECK]
27 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] 27 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
28 fsmagic:= hex value 28 fsmagic:= hex value
29 uid:= decimal value 29 uid:= decimal value
@@ -53,6 +53,7 @@ Description:
53 measure func=BPRM_CHECK 53 measure func=BPRM_CHECK
54 measure func=FILE_MMAP mask=MAY_EXEC 54 measure func=FILE_MMAP mask=MAY_EXEC
55 measure func=FILE_CHECK mask=MAY_READ uid=0 55 measure func=FILE_CHECK mask=MAY_READ uid=0
56 measure func=MODULE_CHECK uid=0
56 appraise fowner=0 57 appraise fowner=0
57 58
58 The default policy measures all executables in bprm_check, 59 The default policy measures all executables in bprm_check,
diff --git a/Makefile b/Makefile
index 540f7b240c77..6f07f4a28b47 100644
--- a/Makefile
+++ b/Makefile
@@ -981,6 +981,12 @@ _modinst_post: _modinst_
981 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst 981 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst
982 $(call cmd,depmod) 982 $(call cmd,depmod)
983 983
984ifeq ($(CONFIG_MODULE_SIG), y)
985PHONY += modules_sign
986modules_sign:
987 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign
988endif
989
984else # CONFIG_MODULES 990else # CONFIG_MODULES
985 991
986# Modules not configured 992# Modules not configured
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index ac03bdb4ae44..4da7cde70b5d 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -405,6 +405,7 @@
405#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) 405#define __NR_process_vm_readv (__NR_SYSCALL_BASE+376)
406#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) 406#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
407 /* 378 for kcmp */ 407 /* 378 for kcmp */
408#define __NR_finit_module (__NR_SYSCALL_BASE+379)
408 409
409/* 410/*
410 * This may need to be greater than __NR_last_syscall+1 in order to 411 * This may need to be greater than __NR_last_syscall+1 in order to
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 5935b6a02e6e..a4fda4e7a372 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -388,6 +388,7 @@
388 CALL(sys_process_vm_readv) 388 CALL(sys_process_vm_readv)
389 CALL(sys_process_vm_writev) 389 CALL(sys_process_vm_writev)
390 CALL(sys_ni_syscall) /* reserved for sys_kcmp */ 390 CALL(sys_ni_syscall) /* reserved for sys_kcmp */
391 CALL(sys_finit_module)
391#ifndef syscalls_counted 392#ifndef syscalls_counted
392.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 393.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
393#define syscalls_counted 394#define syscalls_counted
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
index 37400f5869e6..51123f985eb5 100644
--- a/arch/cris/kernel/module.c
+++ b/arch/cris/kernel/module.c
@@ -32,8 +32,6 @@
32#ifdef CONFIG_ETRAX_KMALLOCED_MODULES 32#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
33void *module_alloc(unsigned long size) 33void *module_alloc(unsigned long size)
34{ 34{
35 if (size == 0)
36 return NULL;
37 return kmalloc(size, GFP_KERNEL); 35 return kmalloc(size, GFP_KERNEL);
38} 36}
39 37
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 5e34ccf39a49..2a625fb063e1 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -214,8 +214,6 @@ static inline int reassemble_22(int as22)
214 214
215void *module_alloc(unsigned long size) 215void *module_alloc(unsigned long size)
216{ 216{
217 if (size == 0)
218 return NULL;
219 /* using RWX means less protection for modules, but it's 217 /* using RWX means less protection for modules, but it's
220 * easier than trying to map the text, data, init_text and 218 * easier than trying to map the text, data, init_text and
221 * init_data correctly */ 219 * init_data correctly */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index cec8aae5cbf8..97909d3b1d7b 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -356,3 +356,4 @@ COMPAT_SYS_SPU(sendmmsg)
356SYSCALL_SPU(setns) 356SYSCALL_SPU(setns)
357COMPAT_SYS(process_vm_readv) 357COMPAT_SYS(process_vm_readv)
358COMPAT_SYS(process_vm_writev) 358COMPAT_SYS(process_vm_writev)
359SYSCALL(finit_module)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index bcbbe413c606..29365e15ed7c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
12#include <uapi/asm/unistd.h> 12#include <uapi/asm/unistd.h>
13 13
14 14
15#define __NR_syscalls 353 15#define __NR_syscalls 354
16 16
17#define __NR__exit __NR_exit 17#define __NR__exit __NR_exit
18#define NR_syscalls __NR_syscalls 18#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index 380b5d37a904..8c478c6c6b1e 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -375,6 +375,7 @@
375#define __NR_setns 350 375#define __NR_setns 350
376#define __NR_process_vm_readv 351 376#define __NR_process_vm_readv 351
377#define __NR_process_vm_writev 352 377#define __NR_process_vm_writev 352
378#define __NR_finit_module 353
378 379
379 380
380#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ 381#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
index f1ddc0d23679..4435488ebe25 100644
--- a/arch/sparc/kernel/module.c
+++ b/arch/sparc/kernel/module.c
@@ -43,10 +43,6 @@ void *module_alloc(unsigned long size)
43{ 43{
44 void *ret; 44 void *ret;
45 45
46 /* We handle the zero case fine, unlike vmalloc */
47 if (size == 0)
48 return NULL;
49
50 ret = module_map(size); 46 ret = module_map(size);
51 if (ret) 47 if (ret)
52 memset(ret, 0, size); 48 memset(ret, 0, size);
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
index 243ffebe38d6..4918d91bc3a6 100644
--- a/arch/tile/kernel/module.c
+++ b/arch/tile/kernel/module.c
@@ -42,8 +42,6 @@ void *module_alloc(unsigned long size)
42 int i = 0; 42 int i = 0;
43 int npages; 43 int npages;
44 44
45 if (size == 0)
46 return NULL;
47 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; 45 npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
48 pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL); 46 pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
49 if (pages == NULL) 47 if (pages == NULL)
diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c
index 8fbe8577f5e6..16bd1495b934 100644
--- a/arch/unicore32/kernel/module.c
+++ b/arch/unicore32/kernel/module.c
@@ -27,9 +27,6 @@ void *module_alloc(unsigned long size)
27 struct vm_struct *area; 27 struct vm_struct *area;
28 28
29 size = PAGE_ALIGN(size); 29 size = PAGE_ALIGN(size);
30 if (!size)
31 return NULL;
32
33 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); 30 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
34 if (!area) 31 if (!area)
35 return NULL; 32 return NULL;
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index ee3c220ee500..05f404f53f59 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -356,3 +356,4 @@
356347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv 356347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
357348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev 357348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
358349 i386 kcmp sys_kcmp 358349 i386 kcmp sys_kcmp
359350 i386 finit_module sys_finit_module
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index a582bfed95bb..7c58c84b7bc8 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -319,6 +319,7 @@
319310 64 process_vm_readv sys_process_vm_readv 319310 64 process_vm_readv sys_process_vm_readv
320311 64 process_vm_writev sys_process_vm_writev 320311 64 process_vm_writev sys_process_vm_writev
321312 common kcmp sys_kcmp 321312 common kcmp sys_kcmp
322313 common finit_module sys_finit_module
322 323
323# 324#
324# x32-specific system call numbers start at 512 to avoid cache impact 325# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/asn1.h b/include/linux/asn1.h
index 5c3f4e4b9a23..eed6982860ba 100644
--- a/include/linux/asn1.h
+++ b/include/linux/asn1.h
@@ -64,4 +64,6 @@ enum asn1_tag {
64 ASN1_LONG_TAG = 31 /* Long form tag */ 64 ASN1_LONG_TAG = 31 /* Long form tag */
65}; 65};
66 66
67#define ASN1_INDEFINITE_LENGTH 0x80
68
67#endif /* _LINUX_ASN1_H */ 69#endif /* _LINUX_ASN1_H */
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index dc16a858e77c..662fd1b4c42a 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -31,6 +31,8 @@
31 31
32#define __linktime_error(message) __attribute__((__error__(message))) 32#define __linktime_error(message) __attribute__((__error__(message)))
33 33
34#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
35
34#if __GNUC_MINOR__ >= 5 36#if __GNUC_MINOR__ >= 5
35/* 37/*
36 * Mark a position in code as unreachable. This can be used to 38 * Mark a position in code as unreachable. This can be used to
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index b121554f1fe2..dd852b73b286 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -44,6 +44,10 @@ extern void __chk_io_ptr(const volatile void __iomem *);
44# define __rcu 44# define __rcu
45#endif 45#endif
46 46
47/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
48#define ___PASTE(a,b) a##b
49#define __PASTE(a,b) ___PASTE(a,b)
50
47#ifdef __KERNEL__ 51#ifdef __KERNEL__
48 52
49#ifdef __GNUC__ 53#ifdef __GNUC__
@@ -166,6 +170,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
166 (typeof(ptr)) (__ptr + (off)); }) 170 (typeof(ptr)) (__ptr + (off)); })
167#endif 171#endif
168 172
173/* Not-quite-unique ID. */
174#ifndef __UNIQUE_ID
175# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
176#endif
177
169#endif /* __KERNEL__ */ 178#endif /* __KERNEL__ */
170 179
171#endif /* __ASSEMBLY__ */ 180#endif /* __ASSEMBLY__ */
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 2c7223d7e73b..86c361e947b9 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -18,6 +18,7 @@ extern int ima_bprm_check(struct linux_binprm *bprm);
18extern int ima_file_check(struct file *file, int mask); 18extern int ima_file_check(struct file *file, int mask);
19extern void ima_file_free(struct file *file); 19extern void ima_file_free(struct file *file);
20extern int ima_file_mmap(struct file *file, unsigned long prot); 20extern int ima_file_mmap(struct file *file, unsigned long prot);
21extern int ima_module_check(struct file *file);
21 22
22#else 23#else
23static inline int ima_bprm_check(struct linux_binprm *bprm) 24static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -40,6 +41,11 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
40 return 0; 41 return 0;
41} 42}
42 43
44static inline int ima_module_check(struct file *file)
45{
46 return 0;
47}
48
43#endif /* CONFIG_IMA_H */ 49#endif /* CONFIG_IMA_H */
44 50
45#ifdef CONFIG_IMA_APPRAISE 51#ifdef CONFIG_IMA_APPRAISE
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index d6a58065c09c..137b4198fc03 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -16,17 +16,15 @@
16/* Chosen so that structs with an unsigned long line up. */ 16/* Chosen so that structs with an unsigned long line up. */
17#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) 17#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
18 18
19#define ___module_cat(a,b) __mod_ ## a ## b
20#define __module_cat(a,b) ___module_cat(a,b)
21#ifdef MODULE 19#ifdef MODULE
22#define __MODULE_INFO(tag, name, info) \ 20#define __MODULE_INFO(tag, name, info) \
23static const char __module_cat(name,__LINE__)[] \ 21static const char __UNIQUE_ID(name)[] \
24 __used __attribute__((section(".modinfo"), unused, aligned(1))) \ 22 __used __attribute__((section(".modinfo"), unused, aligned(1))) \
25 = __stringify(tag) "=" info 23 = __stringify(tag) "=" info
26#else /* !MODULE */ 24#else /* !MODULE */
27/* This struct is here for syntactic coherency, it is not used */ 25/* This struct is here for syntactic coherency, it is not used */
28#define __MODULE_INFO(tag, name, info) \ 26#define __MODULE_INFO(tag, name, info) \
29 struct __module_cat(name,__LINE__) {} 27 struct __UNIQUE_ID(name) {}
30#endif 28#endif
31#define __MODULE_PARM_TYPE(name, _type) \ 29#define __MODULE_PARM_TYPE(name, _type) \
32 __MODULE_INFO(parmtype, name##type, #name ":" _type) 30 __MODULE_INFO(parmtype, name##type, #name ":" _type)
diff --git a/include/linux/security.h b/include/linux/security.h
index 05e88bdcf7d9..0f6afc657f77 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -694,6 +694,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
694 * userspace to load a kernel module with the given name. 694 * userspace to load a kernel module with the given name.
695 * @kmod_name name of the module requested by the kernel 695 * @kmod_name name of the module requested by the kernel
696 * Return 0 if successful. 696 * Return 0 if successful.
697 * @kernel_module_from_file:
698 * Load a kernel module from userspace.
699 * @file contains the file structure pointing to the file containing
700 * the kernel module to load. If the module is being loaded from a blob,
701 * this argument will be NULL.
702 * Return 0 if permission is granted.
697 * @task_fix_setuid: 703 * @task_fix_setuid:
698 * Update the module's state after setting one or more of the user 704 * Update the module's state after setting one or more of the user
699 * identity attributes of the current process. The @flags parameter 705 * identity attributes of the current process. The @flags parameter
@@ -1508,6 +1514,7 @@ struct security_operations {
1508 int (*kernel_act_as)(struct cred *new, u32 secid); 1514 int (*kernel_act_as)(struct cred *new, u32 secid);
1509 int (*kernel_create_files_as)(struct cred *new, struct inode *inode); 1515 int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
1510 int (*kernel_module_request)(char *kmod_name); 1516 int (*kernel_module_request)(char *kmod_name);
1517 int (*kernel_module_from_file)(struct file *file);
1511 int (*task_fix_setuid) (struct cred *new, const struct cred *old, 1518 int (*task_fix_setuid) (struct cred *new, const struct cred *old,
1512 int flags); 1519 int flags);
1513 int (*task_setpgid) (struct task_struct *p, pid_t pgid); 1520 int (*task_setpgid) (struct task_struct *p, pid_t pgid);
@@ -1765,6 +1772,7 @@ void security_transfer_creds(struct cred *new, const struct cred *old);
1765int security_kernel_act_as(struct cred *new, u32 secid); 1772int security_kernel_act_as(struct cred *new, u32 secid);
1766int security_kernel_create_files_as(struct cred *new, struct inode *inode); 1773int security_kernel_create_files_as(struct cred *new, struct inode *inode);
1767int security_kernel_module_request(char *kmod_name); 1774int security_kernel_module_request(char *kmod_name);
1775int security_kernel_module_from_file(struct file *file);
1768int security_task_fix_setuid(struct cred *new, const struct cred *old, 1776int security_task_fix_setuid(struct cred *new, const struct cred *old,
1769 int flags); 1777 int flags);
1770int security_task_setpgid(struct task_struct *p, pid_t pgid); 1778int security_task_setpgid(struct task_struct *p, pid_t pgid);
@@ -2278,6 +2286,11 @@ static inline int security_kernel_module_request(char *kmod_name)
2278 return 0; 2286 return 0;
2279} 2287}
2280 2288
2289static inline int security_kernel_module_from_file(struct file *file)
2290{
2291 return 0;
2292}
2293
2281static inline int security_task_fix_setuid(struct cred *new, 2294static inline int security_task_fix_setuid(struct cred *new,
2282 const struct cred *old, 2295 const struct cred *old,
2283 int flags) 2296 int flags)
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 36c3b07c5119..6caee34bf8a2 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -880,4 +880,5 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
880 880
881asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type, 881asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
882 unsigned long idx1, unsigned long idx2); 882 unsigned long idx1, unsigned long idx2);
883asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags);
883#endif 884#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 6e595ba545f4..2c531f478410 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -690,9 +690,11 @@ __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
690 compat_sys_process_vm_writev) 690 compat_sys_process_vm_writev)
691#define __NR_kcmp 272 691#define __NR_kcmp 272
692__SYSCALL(__NR_kcmp, sys_kcmp) 692__SYSCALL(__NR_kcmp, sys_kcmp)
693#define __NR_finit_module 273
694__SYSCALL(__NR_finit_module, sys_finit_module)
693 695
694#undef __NR_syscalls 696#undef __NR_syscalls
695#define __NR_syscalls 273 697#define __NR_syscalls 274
696 698
697/* 699/*
698 * All syscalls below here should go away really, 700 * All syscalls below here should go away really,
diff --git a/include/uapi/linux/module.h b/include/uapi/linux/module.h
new file mode 100644
index 000000000000..38da4258b12f
--- /dev/null
+++ b/include/uapi/linux/module.h
@@ -0,0 +1,8 @@
1#ifndef _UAPI_LINUX_MODULE_H
2#define _UAPI_LINUX_MODULE_H
3
4/* Flags for sys_finit_module: */
5#define MODULE_INIT_IGNORE_MODVERSIONS 1
6#define MODULE_INIT_IGNORE_VERMAGIC 2
7
8#endif /* _UAPI_LINUX_MODULE_H */
diff --git a/kernel/Makefile b/kernel/Makefile
index ac0d533eb7de..6c072b6da239 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 000000000000..246b4c6e6135
--- /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 767e559dfb10..045504fffbb2 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 808bd62e1723..250092c1d57d 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
2466 || !elf_check_arch(info->hdr)
2467 || info->hdr->e_shentsize != sizeof(Elf_Shdr))
2468 return -ENOEXEC;
2469
2470 if (info->hdr->e_shoff >= info->len
2471 || (info->hdr->e_shnum * sizeof(Elf_Shdr) >
2472 info->len - info->hdr->e_shoff))
2473 return -ENOEXEC;
2474
2475 return 0;
2476}
2477
2478/* Sets info->hdr and info->len. */
2479static int copy_module_from_user(const void __user *umod, unsigned long len,
2480 struct load_info *info)
2465{ 2481{
2466 int err; 2482 int err;
2467 Elf_Ehdr *hdr;
2468 2483
2469 if (len < sizeof(*hdr)) 2484 info->len = len;
2485 if (info->len < sizeof(*(info->hdr)))
2470 return -ENOEXEC; 2486 return -ENOEXEC;
2471 2487
2488 err = security_kernel_module_from_file(NULL);
2489 if (err)
2490 return err;
2491
2472 /* Suck in entire file: we'll want most of it. */ 2492 /* Suck in entire file: we'll want most of it. */
2473 if ((hdr = vmalloc(len)) == NULL) 2493 info->hdr = vmalloc(info->len);
2494 if (!info->hdr)
2474 return -ENOMEM; 2495 return -ENOMEM;
2475 2496
2476 if (copy_from_user(hdr, umod, len) != 0) { 2497 if (copy_from_user(info->hdr, umod, info->len) != 0) {
2477 err = -EFAULT; 2498 vfree(info->hdr);
2478 goto free_hdr; 2499 return -EFAULT;
2479 } 2500 }
2480 2501
2481 err = module_sig_check(info, hdr, &len); 2502 return 0;
2503}
2504
2505/* Sets info->hdr and info->len. */
2506static int copy_module_from_fd(int fd, struct load_info *info)
2507{
2508 struct file *file;
2509 int err;
2510 struct kstat stat;
2511 loff_t pos;
2512 ssize_t bytes = 0;
2513
2514 file = fget(fd);
2515 if (!file)
2516 return -ENOEXEC;
2517
2518 err = security_kernel_module_from_file(file);
2482 if (err) 2519 if (err)
2483 goto free_hdr; 2520 goto out;
2484 2521
2485 /* Sanity checks against insmoding binaries or wrong arch, 2522 err = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
2486 weird elf version */ 2523 if (err)
2487 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 2524 goto out;
2488 || hdr->e_type != ET_REL
2489 || !elf_check_arch(hdr)
2490 || hdr->e_shentsize != sizeof(Elf_Shdr)) {
2491 err = -ENOEXEC;
2492 goto free_hdr;
2493 }
2494 2525
2495 if (hdr->e_shoff >= len || 2526 if (stat.size > INT_MAX) {
2496 hdr->e_shnum * sizeof(Elf_Shdr) > len - hdr->e_shoff) { 2527 err = -EFBIG;
2497 err = -ENOEXEC; 2528 goto out;
2498 goto free_hdr; 2529 }
2530 info->hdr = vmalloc(stat.size);
2531 if (!info->hdr) {
2532 err = -ENOMEM;
2533 goto out;
2499 } 2534 }
2500 2535
2501 info->hdr = hdr; 2536 pos = 0;
2502 info->len = len; 2537 while (pos < stat.size) {
2503 return 0; 2538 bytes = kernel_read(file, pos, (char *)(info->hdr) + pos,
2539 stat.size - pos);
2540 if (bytes < 0) {
2541 vfree(info->hdr);
2542 err = bytes;
2543 goto out;
2544 }
2545 if (bytes == 0)
2546 break;
2547 pos += bytes;
2548 }
2549 info->len = pos;
2504 2550
2505free_hdr: 2551out:
2506 vfree(hdr); 2552 fput(file);
2507 return err; 2553 return err;
2508} 2554}
2509 2555
@@ -2512,7 +2558,7 @@ static void free_copy(struct load_info *info)
2512 vfree(info->hdr); 2558 vfree(info->hdr);
2513} 2559}
2514 2560
2515static int rewrite_section_headers(struct load_info *info) 2561static int rewrite_section_headers(struct load_info *info, int flags)
2516{ 2562{
2517 unsigned int i; 2563 unsigned int i;
2518 2564
@@ -2540,7 +2586,10 @@ static int rewrite_section_headers(struct load_info *info)
2540 } 2586 }
2541 2587
2542 /* Track but don't keep modinfo and version sections. */ 2588 /* Track but don't keep modinfo and version sections. */
2543 info->index.vers = find_sec(info, "__versions"); 2589 if (flags & MODULE_INIT_IGNORE_MODVERSIONS)
2590 info->index.vers = 0; /* Pretend no __versions section! */
2591 else
2592 info->index.vers = find_sec(info, "__versions");
2544 info->index.info = find_sec(info, ".modinfo"); 2593 info->index.info = find_sec(info, ".modinfo");
2545 info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC; 2594 info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
2546 info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC; 2595 info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
@@ -2555,7 +2604,7 @@ static int rewrite_section_headers(struct load_info *info)
2555 * Return the temporary module pointer (we'll replace it with the final 2604 * Return the temporary module pointer (we'll replace it with the final
2556 * one when we move the module sections around). 2605 * one when we move the module sections around).
2557 */ 2606 */
2558static struct module *setup_load_info(struct load_info *info) 2607static struct module *setup_load_info(struct load_info *info, int flags)
2559{ 2608{
2560 unsigned int i; 2609 unsigned int i;
2561 int err; 2610 int err;
@@ -2566,7 +2615,7 @@ static struct module *setup_load_info(struct load_info *info)
2566 info->secstrings = (void *)info->hdr 2615 info->secstrings = (void *)info->hdr
2567 + info->sechdrs[info->hdr->e_shstrndx].sh_offset; 2616 + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
2568 2617
2569 err = rewrite_section_headers(info); 2618 err = rewrite_section_headers(info, flags);
2570 if (err) 2619 if (err)
2571 return ERR_PTR(err); 2620 return ERR_PTR(err);
2572 2621
@@ -2604,11 +2653,14 @@ static struct module *setup_load_info(struct load_info *info)
2604 return mod; 2653 return mod;
2605} 2654}
2606 2655
2607static int check_modinfo(struct module *mod, struct load_info *info) 2656static int check_modinfo(struct module *mod, struct load_info *info, int flags)
2608{ 2657{
2609 const char *modmagic = get_modinfo(info, "vermagic"); 2658 const char *modmagic = get_modinfo(info, "vermagic");
2610 int err; 2659 int err;
2611 2660
2661 if (flags & MODULE_INIT_IGNORE_VERMAGIC)
2662 modmagic = NULL;
2663
2612 /* This is allowed: modprobe --force will invalidate it. */ 2664 /* This is allowed: modprobe --force will invalidate it. */
2613 if (!modmagic) { 2665 if (!modmagic) {
2614 err = try_to_force_load(mod, "bad vermagic"); 2666 err = try_to_force_load(mod, "bad vermagic");
@@ -2738,20 +2790,23 @@ static int move_module(struct module *mod, struct load_info *info)
2738 memset(ptr, 0, mod->core_size); 2790 memset(ptr, 0, mod->core_size);
2739 mod->module_core = ptr; 2791 mod->module_core = ptr;
2740 2792
2741 ptr = module_alloc_update_bounds(mod->init_size); 2793 if (mod->init_size) {
2742 /* 2794 ptr = module_alloc_update_bounds(mod->init_size);
2743 * The pointer to this block is stored in the module structure 2795 /*
2744 * which is inside the block. This block doesn't need to be 2796 * The pointer to this block is stored in the module structure
2745 * scanned as it contains data and code that will be freed 2797 * which is inside the block. This block doesn't need to be
2746 * after the module is initialized. 2798 * scanned as it contains data and code that will be freed
2747 */ 2799 * after the module is initialized.
2748 kmemleak_ignore(ptr); 2800 */
2749 if (!ptr && mod->init_size) { 2801 kmemleak_ignore(ptr);
2750 module_free(mod, mod->module_core); 2802 if (!ptr) {
2751 return -ENOMEM; 2803 module_free(mod, mod->module_core);
2752 } 2804 return -ENOMEM;
2753 memset(ptr, 0, mod->init_size); 2805 }
2754 mod->module_init = ptr; 2806 memset(ptr, 0, mod->init_size);
2807 mod->module_init = ptr;
2808 } else
2809 mod->module_init = NULL;
2755 2810
2756 /* Transfer each section which specifies SHF_ALLOC */ 2811 /* Transfer each section which specifies SHF_ALLOC */
2757 pr_debug("final section addresses:\n"); 2812 pr_debug("final section addresses:\n");
@@ -2844,18 +2899,18 @@ int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
2844 return 0; 2899 return 0;
2845} 2900}
2846 2901
2847static struct module *layout_and_allocate(struct load_info *info) 2902static struct module *layout_and_allocate(struct load_info *info, int flags)
2848{ 2903{
2849 /* Module within temporary copy. */ 2904 /* Module within temporary copy. */
2850 struct module *mod; 2905 struct module *mod;
2851 Elf_Shdr *pcpusec; 2906 Elf_Shdr *pcpusec;
2852 int err; 2907 int err;
2853 2908
2854 mod = setup_load_info(info); 2909 mod = setup_load_info(info, flags);
2855 if (IS_ERR(mod)) 2910 if (IS_ERR(mod))
2856 return mod; 2911 return mod;
2857 2912
2858 err = check_modinfo(mod, info); 2913 err = check_modinfo(mod, info, flags);
2859 if (err) 2914 if (err)
2860 return ERR_PTR(err); 2915 return ERR_PTR(err);
2861 2916
@@ -2942,33 +2997,124 @@ static bool finished_loading(const char *name)
2942 return ret; 2997 return ret;
2943} 2998}
2944 2999
3000/* Call module constructors. */
3001static void do_mod_ctors(struct module *mod)
3002{
3003#ifdef CONFIG_CONSTRUCTORS
3004 unsigned long i;
3005
3006 for (i = 0; i < mod->num_ctors; i++)
3007 mod->ctors[i]();
3008#endif
3009}
3010
3011/* This is where the real work happens */
3012static int do_init_module(struct module *mod)
3013{
3014 int ret = 0;
3015
3016 blocking_notifier_call_chain(&module_notify_list,
3017 MODULE_STATE_COMING, mod);
3018
3019 /* Set RO and NX regions for core */
3020 set_section_ro_nx(mod->module_core,
3021 mod->core_text_size,
3022 mod->core_ro_size,
3023 mod->core_size);
3024
3025 /* Set RO and NX regions for init */
3026 set_section_ro_nx(mod->module_init,
3027 mod->init_text_size,
3028 mod->init_ro_size,
3029 mod->init_size);
3030
3031 do_mod_ctors(mod);
3032 /* Start the module */
3033 if (mod->init != NULL)
3034 ret = do_one_initcall(mod->init);
3035 if (ret < 0) {
3036 /* Init routine failed: abort. Try to protect us from
3037 buggy refcounters. */
3038 mod->state = MODULE_STATE_GOING;
3039 synchronize_sched();
3040 module_put(mod);
3041 blocking_notifier_call_chain(&module_notify_list,
3042 MODULE_STATE_GOING, mod);
3043 free_module(mod);
3044 wake_up_all(&module_wq);
3045 return ret;
3046 }
3047 if (ret > 0) {
3048 printk(KERN_WARNING
3049"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
3050"%s: loading module anyway...\n",
3051 __func__, mod->name, ret,
3052 __func__);
3053 dump_stack();
3054 }
3055
3056 /* Now it's a first class citizen! */
3057 mod->state = MODULE_STATE_LIVE;
3058 blocking_notifier_call_chain(&module_notify_list,
3059 MODULE_STATE_LIVE, mod);
3060
3061 /* We need to finish all async code before the module init sequence is done */
3062 async_synchronize_full();
3063
3064 mutex_lock(&module_mutex);
3065 /* Drop initial reference. */
3066 module_put(mod);
3067 trim_init_extable(mod);
3068#ifdef CONFIG_KALLSYMS
3069 mod->num_symtab = mod->core_num_syms;
3070 mod->symtab = mod->core_symtab;
3071 mod->strtab = mod->core_strtab;
3072#endif
3073 unset_module_init_ro_nx(mod);
3074 module_free(mod, mod->module_init);
3075 mod->module_init = NULL;
3076 mod->init_size = 0;
3077 mod->init_ro_size = 0;
3078 mod->init_text_size = 0;
3079 mutex_unlock(&module_mutex);
3080 wake_up_all(&module_wq);
3081
3082 return 0;
3083}
3084
3085static int may_init_module(void)
3086{
3087 if (!capable(CAP_SYS_MODULE) || modules_disabled)
3088 return -EPERM;
3089
3090 return 0;
3091}
3092
2945/* Allocate and load the module: note that size of section 0 is always 3093/* Allocate and load the module: note that size of section 0 is always
2946 zero, and we rely on this for optional sections. */ 3094 zero, and we rely on this for optional sections. */
2947static struct module *load_module(void __user *umod, 3095static int load_module(struct load_info *info, const char __user *uargs,
2948 unsigned long len, 3096 int flags)
2949 const char __user *uargs)
2950{ 3097{
2951 struct load_info info = { NULL, };
2952 struct module *mod, *old; 3098 struct module *mod, *old;
2953 long err; 3099 long err;
2954 3100
2955 pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", 3101 err = module_sig_check(info);
2956 umod, len, uargs); 3102 if (err)
3103 goto free_copy;
2957 3104
2958 /* Copy in the blobs from userspace, check they are vaguely sane. */ 3105 err = elf_header_check(info);
2959 err = copy_and_check(&info, umod, len, uargs);
2960 if (err) 3106 if (err)
2961 return ERR_PTR(err); 3107 goto free_copy;
2962 3108
2963 /* Figure out module layout, and allocate all the memory. */ 3109 /* Figure out module layout, and allocate all the memory. */
2964 mod = layout_and_allocate(&info); 3110 mod = layout_and_allocate(info, flags);
2965 if (IS_ERR(mod)) { 3111 if (IS_ERR(mod)) {
2966 err = PTR_ERR(mod); 3112 err = PTR_ERR(mod);
2967 goto free_copy; 3113 goto free_copy;
2968 } 3114 }
2969 3115
2970#ifdef CONFIG_MODULE_SIG 3116#ifdef CONFIG_MODULE_SIG
2971 mod->sig_ok = info.sig_ok; 3117 mod->sig_ok = info->sig_ok;
2972 if (!mod->sig_ok) 3118 if (!mod->sig_ok)
2973 add_taint_module(mod, TAINT_FORCED_MODULE); 3119 add_taint_module(mod, TAINT_FORCED_MODULE);
2974#endif 3120#endif
@@ -2980,25 +3126,25 @@ static struct module *load_module(void __user *umod,
2980 3126
2981 /* Now we've got everything in the final locations, we can 3127 /* Now we've got everything in the final locations, we can
2982 * find optional sections. */ 3128 * find optional sections. */
2983 find_module_sections(mod, &info); 3129 find_module_sections(mod, info);
2984 3130
2985 err = check_module_license_and_versions(mod); 3131 err = check_module_license_and_versions(mod);
2986 if (err) 3132 if (err)
2987 goto free_unload; 3133 goto free_unload;
2988 3134
2989 /* Set up MODINFO_ATTR fields */ 3135 /* Set up MODINFO_ATTR fields */
2990 setup_modinfo(mod, &info); 3136 setup_modinfo(mod, info);
2991 3137
2992 /* Fix up syms, so that st_value is a pointer to location. */ 3138 /* Fix up syms, so that st_value is a pointer to location. */
2993 err = simplify_symbols(mod, &info); 3139 err = simplify_symbols(mod, info);
2994 if (err < 0) 3140 if (err < 0)
2995 goto free_modinfo; 3141 goto free_modinfo;
2996 3142
2997 err = apply_relocations(mod, &info); 3143 err = apply_relocations(mod, info);
2998 if (err < 0) 3144 if (err < 0)
2999 goto free_modinfo; 3145 goto free_modinfo;
3000 3146
3001 err = post_relocation(mod, &info); 3147 err = post_relocation(mod, info);
3002 if (err < 0) 3148 if (err < 0)
3003 goto free_modinfo; 3149 goto free_modinfo;
3004 3150
@@ -3038,14 +3184,14 @@ again:
3038 } 3184 }
3039 3185
3040 /* This has to be done once we're sure module name is unique. */ 3186 /* This has to be done once we're sure module name is unique. */
3041 dynamic_debug_setup(info.debug, info.num_debug); 3187 dynamic_debug_setup(info->debug, info->num_debug);
3042 3188
3043 /* Find duplicate symbols */ 3189 /* Find duplicate symbols */
3044 err = verify_export_symbols(mod); 3190 err = verify_export_symbols(mod);
3045 if (err < 0) 3191 if (err < 0)
3046 goto ddebug; 3192 goto ddebug;
3047 3193
3048 module_bug_finalize(info.hdr, info.sechdrs, mod); 3194 module_bug_finalize(info->hdr, info->sechdrs, mod);
3049 list_add_rcu(&mod->list, &modules); 3195 list_add_rcu(&mod->list, &modules);
3050 mutex_unlock(&module_mutex); 3196 mutex_unlock(&module_mutex);
3051 3197
@@ -3056,16 +3202,17 @@ again:
3056 goto unlink; 3202 goto unlink;
3057 3203
3058 /* Link in to syfs. */ 3204 /* Link in to syfs. */
3059 err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp); 3205 err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
3060 if (err < 0) 3206 if (err < 0)
3061 goto unlink; 3207 goto unlink;
3062 3208
3063 /* Get rid of temporary copy. */ 3209 /* Get rid of temporary copy. */
3064 free_copy(&info); 3210 free_copy(info);
3065 3211
3066 /* Done! */ 3212 /* Done! */
3067 trace_module_load(mod); 3213 trace_module_load(mod);
3068 return mod; 3214
3215 return do_init_module(mod);
3069 3216
3070 unlink: 3217 unlink:
3071 mutex_lock(&module_mutex); 3218 mutex_lock(&module_mutex);
@@ -3074,7 +3221,7 @@ again:
3074 module_bug_cleanup(mod); 3221 module_bug_cleanup(mod);
3075 wake_up_all(&module_wq); 3222 wake_up_all(&module_wq);
3076 ddebug: 3223 ddebug:
3077 dynamic_debug_remove(info.debug); 3224 dynamic_debug_remove(info->debug);
3078 unlock: 3225 unlock:
3079 mutex_unlock(&module_mutex); 3226 mutex_unlock(&module_mutex);
3080 synchronize_sched(); 3227 synchronize_sched();
@@ -3086,106 +3233,52 @@ again:
3086 free_unload: 3233 free_unload:
3087 module_unload_free(mod); 3234 module_unload_free(mod);
3088 free_module: 3235 free_module:
3089 module_deallocate(mod, &info); 3236 module_deallocate(mod, info);
3090 free_copy: 3237 free_copy:
3091 free_copy(&info); 3238 free_copy(info);
3092 return ERR_PTR(err); 3239 return err;
3093}
3094
3095/* Call module constructors. */
3096static void do_mod_ctors(struct module *mod)
3097{
3098#ifdef CONFIG_CONSTRUCTORS
3099 unsigned long i;
3100
3101 for (i = 0; i < mod->num_ctors; i++)
3102 mod->ctors[i]();
3103#endif
3104} 3240}
3105 3241
3106/* This is where the real work happens */
3107SYSCALL_DEFINE3(init_module, void __user *, umod, 3242SYSCALL_DEFINE3(init_module, void __user *, umod,
3108 unsigned long, len, const char __user *, uargs) 3243 unsigned long, len, const char __user *, uargs)
3109{ 3244{
3110 struct module *mod; 3245 int err;
3111 int ret = 0; 3246 struct load_info info = { };
3112 3247
3113 /* Must have permission */ 3248 err = may_init_module();
3114 if (!capable(CAP_SYS_MODULE) || modules_disabled) 3249 if (err)
3115 return -EPERM; 3250 return err;
3116 3251
3117 /* Do all the hard work */ 3252 pr_debug("init_module: umod=%p, len=%lu, uargs=%p\n",
3118 mod = load_module(umod, len, uargs); 3253 umod, len, uargs);
3119 if (IS_ERR(mod))
3120 return PTR_ERR(mod);
3121 3254
3122 blocking_notifier_call_chain(&module_notify_list, 3255 err = copy_module_from_user(umod, len, &info);
3123 MODULE_STATE_COMING, mod); 3256 if (err)
3257 return err;
3124 3258
3125 /* Set RO and NX regions for core */ 3259 return load_module(&info, uargs, 0);
3126 set_section_ro_nx(mod->module_core, 3260}
3127 mod->core_text_size,
3128 mod->core_ro_size,
3129 mod->core_size);
3130 3261
3131 /* Set RO and NX regions for init */ 3262SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
3132 set_section_ro_nx(mod->module_init, 3263{
3133 mod->init_text_size, 3264 int err;
3134 mod->init_ro_size, 3265 struct load_info info = { };
3135 mod->init_size);
3136 3266
3137 do_mod_ctors(mod); 3267 err = may_init_module();
3138 /* Start the module */ 3268 if (err)
3139 if (mod->init != NULL) 3269 return err;
3140 ret = do_one_initcall(mod->init);
3141 if (ret < 0) {
3142 /* Init routine failed: abort. Try to protect us from
3143 buggy refcounters. */
3144 mod->state = MODULE_STATE_GOING;
3145 synchronize_sched();
3146 module_put(mod);
3147 blocking_notifier_call_chain(&module_notify_list,
3148 MODULE_STATE_GOING, mod);
3149 free_module(mod);
3150 wake_up_all(&module_wq);
3151 return ret;
3152 }
3153 if (ret > 0) {
3154 printk(KERN_WARNING
3155"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n"
3156"%s: loading module anyway...\n",
3157 __func__, mod->name, ret,
3158 __func__);
3159 dump_stack();
3160 }
3161 3270
3162 /* Now it's a first class citizen! */ 3271 pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags);
3163 mod->state = MODULE_STATE_LIVE;
3164 blocking_notifier_call_chain(&module_notify_list,
3165 MODULE_STATE_LIVE, mod);
3166 3272
3167 /* We need to finish all async code before the module init sequence is done */ 3273 if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS
3168 async_synchronize_full(); 3274 |MODULE_INIT_IGNORE_VERMAGIC))
3275 return -EINVAL;
3169 3276
3170 mutex_lock(&module_mutex); 3277 err = copy_module_from_fd(fd, &info);
3171 /* Drop initial reference. */ 3278 if (err)
3172 module_put(mod); 3279 return err;
3173 trim_init_extable(mod);
3174#ifdef CONFIG_KALLSYMS
3175 mod->num_symtab = mod->core_num_syms;
3176 mod->symtab = mod->core_symtab;
3177 mod->strtab = mod->core_strtab;
3178#endif
3179 unset_module_init_ro_nx(mod);
3180 module_free(mod, mod->module_init);
3181 mod->module_init = NULL;
3182 mod->init_size = 0;
3183 mod->init_ro_size = 0;
3184 mod->init_text_size = 0;
3185 mutex_unlock(&module_mutex);
3186 wake_up_all(&module_wq);
3187 3280
3188 return 0; 3281 return load_module(&info, uargs, flags);
3189} 3282}
3190 3283
3191static inline int within(unsigned long addr, void *start, unsigned long size) 3284static inline int within(unsigned long addr, void *start, unsigned long size)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index dbff751e4086..395084d4ce16 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -25,6 +25,7 @@ cond_syscall(sys_swapoff);
25cond_syscall(sys_kexec_load); 25cond_syscall(sys_kexec_load);
26cond_syscall(compat_sys_kexec_load); 26cond_syscall(compat_sys_kexec_load);
27cond_syscall(sys_init_module); 27cond_syscall(sys_init_module);
28cond_syscall(sys_finit_module);
28cond_syscall(sys_delete_module); 29cond_syscall(sys_delete_module);
29cond_syscall(sys_socketpair); 30cond_syscall(sys_socketpair);
30cond_syscall(sys_bind); 31cond_syscall(sys_bind);
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
index 5293d2433029..11b9b01fda6b 100644
--- a/lib/asn1_decoder.c
+++ b/lib/asn1_decoder.c
@@ -81,7 +81,7 @@ next_tag:
81 goto next_tag; 81 goto next_tag;
82 } 82 }
83 83
84 if (unlikely((tag & 0x1f) == 0x1f)) { 84 if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) {
85 do { 85 do {
86 if (unlikely(datalen - dp < 2)) 86 if (unlikely(datalen - dp < 2))
87 goto data_overrun_error; 87 goto data_overrun_error;
@@ -96,7 +96,7 @@ next_tag:
96 goto next_tag; 96 goto next_tag;
97 } 97 }
98 98
99 if (unlikely(len == 0x80)) { 99 if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
100 /* Indefinite length */ 100 /* Indefinite length */
101 if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5)) 101 if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5))
102 goto indefinite_len_primitive; 102 goto indefinite_len_primitive;
@@ -222,7 +222,7 @@ next_op:
222 if (unlikely(dp >= datalen - 1)) 222 if (unlikely(dp >= datalen - 1))
223 goto data_overrun_error; 223 goto data_overrun_error;
224 tag = data[dp++]; 224 tag = data[dp++];
225 if (unlikely((tag & 0x1f) == 0x1f)) 225 if (unlikely((tag & 0x1f) == ASN1_LONG_TAG))
226 goto long_tag_not_supported; 226 goto long_tag_not_supported;
227 227
228 if (op & ASN1_OP_MATCH__ANY) { 228 if (op & ASN1_OP_MATCH__ANY) {
@@ -254,7 +254,7 @@ next_op:
254 254
255 len = data[dp++]; 255 len = data[dp++];
256 if (len > 0x7f) { 256 if (len > 0x7f) {
257 if (unlikely(len == 0x80)) { 257 if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
258 /* Indefinite length */ 258 /* Indefinite length */
259 if (unlikely(!(tag & ASN1_CONS_BIT))) 259 if (unlikely(!(tag & ASN1_CONS_BIT)))
260 goto indefinite_len_primitive; 260 goto indefinite_len_primitive;
diff --git a/scripts/Makefile.modsign b/scripts/Makefile.modsign
new file mode 100644
index 000000000000..abfda626dbad
--- /dev/null
+++ b/scripts/Makefile.modsign
@@ -0,0 +1,32 @@
1# ==========================================================================
2# Signing modules
3# ==========================================================================
4
5PHONY := __modsign
6__modsign:
7
8include scripts/Kbuild.include
9
10__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
11modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
12
13PHONY += $(modules)
14__modsign: $(modules)
15 @:
16
17quiet_cmd_sign_ko = SIGN [M] $(2)/$(notdir $@)
18 cmd_sign_ko = $(mod_sign_cmd) $(2)/$(notdir $@)
19
20# Modules built outside the kernel source tree go into extra by default
21INSTALL_MOD_DIR ?= extra
22ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D))
23
24modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D))
25
26$(modules):
27 $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir))
28
29# Declare the contents of the .PHONY variable as phony. We keep that
30# information in a variable se we can use it in if_changed and friends.
31
32.PHONY: $(PHONY)
diff --git a/security/capability.c b/security/capability.c
index b14a30c234b8..0fe5a026aef8 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -395,6 +395,11 @@ static int cap_kernel_module_request(char *kmod_name)
395 return 0; 395 return 0;
396} 396}
397 397
398static int cap_kernel_module_from_file(struct file *file)
399{
400 return 0;
401}
402
398static int cap_task_setpgid(struct task_struct *p, pid_t pgid) 403static int cap_task_setpgid(struct task_struct *p, pid_t pgid)
399{ 404{
400 return 0; 405 return 0;
@@ -967,6 +972,7 @@ void __init security_fixup_ops(struct security_operations *ops)
967 set_to_cap_if_null(ops, kernel_act_as); 972 set_to_cap_if_null(ops, kernel_act_as);
968 set_to_cap_if_null(ops, kernel_create_files_as); 973 set_to_cap_if_null(ops, kernel_create_files_as);
969 set_to_cap_if_null(ops, kernel_module_request); 974 set_to_cap_if_null(ops, kernel_module_request);
975 set_to_cap_if_null(ops, kernel_module_from_file);
970 set_to_cap_if_null(ops, task_fix_setuid); 976 set_to_cap_if_null(ops, task_fix_setuid);
971 set_to_cap_if_null(ops, task_setpgid); 977 set_to_cap_if_null(ops, task_setpgid);
972 set_to_cap_if_null(ops, task_getpgid); 978 set_to_cap_if_null(ops, task_getpgid);
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 6ee8826662cc..3b2adb794f15 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -127,7 +127,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
127struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 127struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
128 128
129/* IMA policy related functions */ 129/* IMA policy related functions */
130enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR }; 130enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
131 131
132int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 132int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
133 int flags); 133 int flags);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index b356884fb3ef..0cea3db21657 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -100,12 +100,12 @@ err_out:
100 * ima_get_action - appraise & measure decision based on policy. 100 * ima_get_action - appraise & measure decision based on policy.
101 * @inode: pointer to inode to measure 101 * @inode: pointer to inode to measure
102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) 103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK)
104 * 104 *
105 * The policy is defined in terms of keypairs: 105 * The policy is defined in terms of keypairs:
106 * subj=, obj=, type=, func=, mask=, fsmagic= 106 * subj=, obj=, type=, func=, mask=, fsmagic=
107 * subj,obj, and type: are LSM specific. 107 * subj,obj, and type: are LSM specific.
108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP 108 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK
109 * mask: contains the permission mask 109 * mask: contains the permission mask
110 * fsmagic: hex value 110 * fsmagic: hex value
111 * 111 *
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 73c9a268253e..45de18e9a6f2 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -280,6 +280,27 @@ int ima_file_check(struct file *file, int mask)
280} 280}
281EXPORT_SYMBOL_GPL(ima_file_check); 281EXPORT_SYMBOL_GPL(ima_file_check);
282 282
283/**
284 * ima_module_check - based on policy, collect/store/appraise measurement.
285 * @file: pointer to the file to be measured/appraised
286 *
287 * Measure/appraise kernel modules based on policy.
288 *
289 * Always return 0 and audit dentry_open failures.
290 * Return code is based upon measurement appraisal.
291 */
292int ima_module_check(struct file *file)
293{
294 int rc;
295
296 if (!file)
297 rc = INTEGRITY_UNKNOWN;
298 else
299 rc = process_measurement(file, file->f_dentry->d_name.name,
300 MAY_EXEC, MODULE_CHECK);
301 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
302}
303
283static int __init init_ima(void) 304static int __init init_ima(void)
284{ 305{
285 int error; 306 int error;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index c7dacd2eab7a..af7d182d5a46 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -80,6 +80,7 @@ static struct ima_rule_entry default_rules[] = {
80 .flags = IMA_FUNC | IMA_MASK}, 80 .flags = IMA_FUNC | IMA_MASK},
81 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID, 81 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID,
82 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 82 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
83 {.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC},
83}; 84};
84 85
85static struct ima_rule_entry default_appraise_rules[] = { 86static struct ima_rule_entry default_appraise_rules[] = {
@@ -401,6 +402,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
401 /* PATH_CHECK is for backwards compat */ 402 /* PATH_CHECK is for backwards compat */
402 else if (strcmp(args[0].from, "PATH_CHECK") == 0) 403 else if (strcmp(args[0].from, "PATH_CHECK") == 0)
403 entry->func = FILE_CHECK; 404 entry->func = FILE_CHECK;
405 else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
406 entry->func = MODULE_CHECK;
404 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 407 else if (strcmp(args[0].from, "FILE_MMAP") == 0)
405 entry->func = FILE_MMAP; 408 entry->func = FILE_MMAP;
406 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 409 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
diff --git a/security/security.c b/security/security.c
index 8dcd4ae10a5f..daa97f4ac9d1 100644
--- a/security/security.c
+++ b/security/security.c
@@ -820,6 +820,16 @@ int security_kernel_module_request(char *kmod_name)
820 return security_ops->kernel_module_request(kmod_name); 820 return security_ops->kernel_module_request(kmod_name);
821} 821}
822 822
823int security_kernel_module_from_file(struct file *file)
824{
825 int ret;
826
827 ret = security_ops->kernel_module_from_file(file);
828 if (ret)
829 return ret;
830 return ima_module_check(file);
831}
832
823int security_task_fix_setuid(struct cred *new, const struct cred *old, 833int security_task_fix_setuid(struct cred *new, const struct cred *old,
824 int flags) 834 int flags)
825{ 835{