aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt1
-rw-r--r--fs/exec.c10
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/inode.c24
-rw-r--r--fs/namei.c8
-rw-r--r--include/linux/ima.h44
-rw-r--r--mm/mmap.c4
7 files changed, 86 insertions, 7 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a2d8805c03d5..7c67b94d1823 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -44,6 +44,7 @@ parameter is applicable:
44 FB The frame buffer device is enabled. 44 FB The frame buffer device is enabled.
45 HW Appropriate hardware is enabled. 45 HW Appropriate hardware is enabled.
46 IA-64 IA-64 architecture is enabled. 46 IA-64 IA-64 architecture is enabled.
47 IMA Integrity measurement architecture is enabled.
47 IOSCHED More than one I/O scheduler is enabled. 48 IOSCHED More than one I/O scheduler is enabled.
48 IP_PNP IP DHCP, BOOTP, or RARP is enabled. 49 IP_PNP IP DHCP, BOOTP, or RARP is enabled.
49 ISAPNP ISA PnP code is enabled. 50 ISAPNP ISA PnP code is enabled.
diff --git a/fs/exec.c b/fs/exec.c
index 02d2e120542d..9c789a525cc4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -45,6 +45,7 @@
45#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
46#include <linux/mount.h> 46#include <linux/mount.h>
47#include <linux/security.h> 47#include <linux/security.h>
48#include <linux/ima.h>
48#include <linux/syscalls.h> 49#include <linux/syscalls.h>
49#include <linux/tsacct_kern.h> 50#include <linux/tsacct_kern.h>
50#include <linux/cn_proc.h> 51#include <linux/cn_proc.h>
@@ -130,6 +131,9 @@ asmlinkage long sys_uselib(const char __user * library)
130 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); 131 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
131 if (error) 132 if (error)
132 goto exit; 133 goto exit;
134 error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
135 if (error)
136 goto exit;
133 137
134 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 138 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
135 error = PTR_ERR(file); 139 error = PTR_ERR(file);
@@ -683,6 +687,9 @@ struct file *open_exec(const char *name)
683 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); 687 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
684 if (err) 688 if (err)
685 goto out_path_put; 689 goto out_path_put;
690 err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
691 if (err)
692 goto out_path_put;
686 693
687 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); 694 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
688 if (IS_ERR(file)) 695 if (IS_ERR(file))
@@ -1209,6 +1216,9 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1209 retval = security_bprm_check(bprm); 1216 retval = security_bprm_check(bprm);
1210 if (retval) 1217 if (retval)
1211 return retval; 1218 return retval;
1219 retval = ima_bprm_check(bprm);
1220 if (retval)
1221 return retval;
1212 1222
1213 /* kernel module loader fixup */ 1223 /* kernel module loader fixup */
1214 /* so we don't try to load run modprobe in kernel space. */ 1224 /* so we don't try to load run modprobe in kernel space. */
diff --git a/fs/file_table.c b/fs/file_table.c
index 0fbcacc3ea75..55895ccc08c6 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/ima.h>
16#include <linux/eventpoll.h> 17#include <linux/eventpoll.h>
17#include <linux/rcupdate.h> 18#include <linux/rcupdate.h>
18#include <linux/mount.h> 19#include <linux/mount.h>
@@ -276,6 +277,7 @@ void __fput(struct file *file)
276 if (file->f_op && file->f_op->release) 277 if (file->f_op && file->f_op->release)
277 file->f_op->release(inode, file); 278 file->f_op->release(inode, file);
278 security_file_free(file); 279 security_file_free(file);
280 ima_file_free(file);
279 if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) 281 if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL))
280 cdev_put(inode->i_cdev); 282 cdev_put(inode->i_cdev);
281 fops_put(file->f_op); 283 fops_put(file->f_op);
diff --git a/fs/inode.c b/fs/inode.c
index 098a2443196f..ed22b14f2202 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -17,6 +17,7 @@
17#include <linux/hash.h> 17#include <linux/hash.h>
18#include <linux/swap.h> 18#include <linux/swap.h>
19#include <linux/security.h> 19#include <linux/security.h>
20#include <linux/ima.h>
20#include <linux/pagemap.h> 21#include <linux/pagemap.h>
21#include <linux/cdev.h> 22#include <linux/cdev.h>
22#include <linux/bootmem.h> 23#include <linux/bootmem.h>
@@ -144,13 +145,13 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
144 inode->i_cdev = NULL; 145 inode->i_cdev = NULL;
145 inode->i_rdev = 0; 146 inode->i_rdev = 0;
146 inode->dirtied_when = 0; 147 inode->dirtied_when = 0;
147 if (security_inode_alloc(inode)) { 148
148 if (inode->i_sb->s_op->destroy_inode) 149 if (security_inode_alloc(inode))
149 inode->i_sb->s_op->destroy_inode(inode); 150 goto out_free_inode;
150 else 151
151 kmem_cache_free(inode_cachep, (inode)); 152 /* allocate and initialize an i_integrity */
152 return NULL; 153 if (ima_inode_alloc(inode))
153 } 154 goto out_free_security;
154 155
155 spin_lock_init(&inode->i_lock); 156 spin_lock_init(&inode->i_lock);
156 lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); 157 lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
@@ -186,6 +187,15 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
186 inode->i_mapping = mapping; 187 inode->i_mapping = mapping;
187 188
188 return inode; 189 return inode;
190
191out_free_security:
192 security_inode_free(inode);
193out_free_inode:
194 if (inode->i_sb->s_op->destroy_inode)
195 inode->i_sb->s_op->destroy_inode(inode);
196 else
197 kmem_cache_free(inode_cachep, (inode));
198 return NULL;
189} 199}
190EXPORT_SYMBOL(inode_init_always); 200EXPORT_SYMBOL(inode_init_always);
191 201
diff --git a/fs/namei.c b/fs/namei.c
index af3783fff1de..734f2b5591bf 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -24,6 +24,7 @@
24#include <linux/fsnotify.h> 24#include <linux/fsnotify.h>
25#include <linux/personality.h> 25#include <linux/personality.h>
26#include <linux/security.h> 26#include <linux/security.h>
27#include <linux/ima.h>
27#include <linux/syscalls.h> 28#include <linux/syscalls.h>
28#include <linux/mount.h> 29#include <linux/mount.h>
29#include <linux/audit.h> 30#include <linux/audit.h>
@@ -860,6 +861,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
860 err = exec_permission_lite(inode); 861 err = exec_permission_lite(inode);
861 if (err == -EAGAIN) 862 if (err == -EAGAIN)
862 err = vfs_permission(nd, MAY_EXEC); 863 err = vfs_permission(nd, MAY_EXEC);
864 if (!err)
865 err = ima_path_check(&nd->path, MAY_EXEC);
863 if (err) 866 if (err)
864 break; 867 break;
865 868
@@ -1525,6 +1528,11 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1525 error = vfs_permission(nd, acc_mode); 1528 error = vfs_permission(nd, acc_mode);
1526 if (error) 1529 if (error)
1527 return error; 1530 return error;
1531
1532 error = ima_path_check(&nd->path,
1533 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
1534 if (error)
1535 return error;
1528 /* 1536 /*
1529 * An append-only file must be opened in append mode for writing. 1537 * An append-only file must be opened in append mode for writing.
1530 */ 1538 */
diff --git a/include/linux/ima.h b/include/linux/ima.h
new file mode 100644
index 000000000000..4ed1e4d962e2
--- /dev/null
+++ b/include/linux/ima.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (C) 2008 IBM Corporation
3 * Author: Mimi Zohar <zohar@us.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
8 */
9
10#include <linux/fs.h>
11
12#ifndef _LINUX_IMA_H
13#define _LINUX_IMA_H
14
15static inline int ima_bprm_check(struct linux_binprm *bprm)
16{
17 return 0;
18}
19
20static inline int ima_inode_alloc(struct inode *inode)
21{
22 return 0;
23}
24
25static inline void ima_inode_free(struct inode *inode)
26{
27 return;
28}
29
30static inline int ima_path_check(struct path *path, int mask)
31{
32 return 0;
33}
34
35static inline void ima_file_free(struct file *file)
36{
37 return;
38}
39
40static inline int ima_file_mmap(struct file *file, unsigned long prot)
41{
42 return 0;
43}
44#endif /* _LINUX_IMA_H */
diff --git a/mm/mmap.c b/mm/mmap.c
index d4855a682ab6..c3647f3b0621 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -20,6 +20,7 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/personality.h> 21#include <linux/personality.h>
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/ima.h>
23#include <linux/hugetlb.h> 24#include <linux/hugetlb.h>
24#include <linux/profile.h> 25#include <linux/profile.h>
25#include <linux/module.h> 26#include <linux/module.h>
@@ -1050,6 +1051,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
1050 error = security_file_mmap(file, reqprot, prot, flags, addr, 0); 1051 error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
1051 if (error) 1052 if (error)
1052 return error; 1053 return error;
1054 error = ima_file_mmap(file, prot);
1055 if (error)
1056 return error;
1053 1057
1054 return mmap_region(file, addr, len, flags, vm_flags, pgoff, 1058 return mmap_region(file, addr, len, flags, vm_flags, pgoff,
1055 accountable); 1059 accountable);