Commit 6146f0d5e47ca4047ffded0fb79b6c25359b386c
Committed by
James Morris
1 parent
659aaf2bb5
Exists in
master
and in
20 other branches
integrity: IMA hooks
This patch replaces the generic integrity hooks, for which IMA registered itself, with IMA integrity hooks in the appropriate places directly in the fs directory. Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Showing 7 changed files with 86 additions and 7 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -44,6 +44,7 @@ |
44 | 44 | FB The frame buffer device is enabled. |
45 | 45 | HW Appropriate hardware is enabled. |
46 | 46 | IA-64 IA-64 architecture is enabled. |
47 | + IMA Integrity measurement architecture is enabled. | |
47 | 48 | IOSCHED More than one I/O scheduler is enabled. |
48 | 49 | IP_PNP IP DHCP, BOOTP, or RARP is enabled. |
49 | 50 | ISAPNP ISA PnP code is enabled. |
fs/exec.c
... | ... | @@ -45,6 +45,7 @@ |
45 | 45 | #include <linux/proc_fs.h> |
46 | 46 | #include <linux/mount.h> |
47 | 47 | #include <linux/security.h> |
48 | +#include <linux/ima.h> | |
48 | 49 | #include <linux/syscalls.h> |
49 | 50 | #include <linux/tsacct_kern.h> |
50 | 51 | #include <linux/cn_proc.h> |
... | ... | @@ -130,6 +131,9 @@ |
130 | 131 | error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); |
131 | 132 | if (error) |
132 | 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 | 138 | file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); |
135 | 139 | error = PTR_ERR(file); |
... | ... | @@ -683,6 +687,9 @@ |
683 | 687 | err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); |
684 | 688 | if (err) |
685 | 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 | 694 | file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); |
688 | 695 | if (IS_ERR(file)) |
... | ... | @@ -1207,6 +1214,9 @@ |
1207 | 1214 | } |
1208 | 1215 | #endif |
1209 | 1216 | retval = security_bprm_check(bprm); |
1217 | + if (retval) | |
1218 | + return retval; | |
1219 | + retval = ima_bprm_check(bprm); | |
1210 | 1220 | if (retval) |
1211 | 1221 | return retval; |
1212 | 1222 |
fs/file_table.c
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | #include <linux/module.h> |
14 | 14 | #include <linux/fs.h> |
15 | 15 | #include <linux/security.h> |
16 | +#include <linux/ima.h> | |
16 | 17 | #include <linux/eventpoll.h> |
17 | 18 | #include <linux/rcupdate.h> |
18 | 19 | #include <linux/mount.h> |
... | ... | @@ -276,6 +277,7 @@ |
276 | 277 | if (file->f_op && file->f_op->release) |
277 | 278 | file->f_op->release(inode, file); |
278 | 279 | security_file_free(file); |
280 | + ima_file_free(file); | |
279 | 281 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) |
280 | 282 | cdev_put(inode->i_cdev); |
281 | 283 | fops_put(file->f_op); |
fs/inode.c
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | #include <linux/hash.h> |
18 | 18 | #include <linux/swap.h> |
19 | 19 | #include <linux/security.h> |
20 | +#include <linux/ima.h> | |
20 | 21 | #include <linux/pagemap.h> |
21 | 22 | #include <linux/cdev.h> |
22 | 23 | #include <linux/bootmem.h> |
23 | 24 | |
... | ... | @@ -144,14 +145,14 @@ |
144 | 145 | inode->i_cdev = NULL; |
145 | 146 | inode->i_rdev = 0; |
146 | 147 | inode->dirtied_when = 0; |
147 | - if (security_inode_alloc(inode)) { | |
148 | - if (inode->i_sb->s_op->destroy_inode) | |
149 | - inode->i_sb->s_op->destroy_inode(inode); | |
150 | - else | |
151 | - kmem_cache_free(inode_cachep, (inode)); | |
152 | - return NULL; | |
153 | - } | |
154 | 148 | |
149 | + if (security_inode_alloc(inode)) | |
150 | + goto out_free_inode; | |
151 | + | |
152 | + /* allocate and initialize an i_integrity */ | |
153 | + if (ima_inode_alloc(inode)) | |
154 | + goto out_free_security; | |
155 | + | |
155 | 156 | spin_lock_init(&inode->i_lock); |
156 | 157 | lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); |
157 | 158 | |
... | ... | @@ -186,6 +187,15 @@ |
186 | 187 | inode->i_mapping = mapping; |
187 | 188 | |
188 | 189 | return inode; |
190 | + | |
191 | +out_free_security: | |
192 | + security_inode_free(inode); | |
193 | +out_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 | } |
190 | 200 | EXPORT_SYMBOL(inode_init_always); |
191 | 201 |
fs/namei.c
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | #include <linux/fsnotify.h> |
25 | 25 | #include <linux/personality.h> |
26 | 26 | #include <linux/security.h> |
27 | +#include <linux/ima.h> | |
27 | 28 | #include <linux/syscalls.h> |
28 | 29 | #include <linux/mount.h> |
29 | 30 | #include <linux/audit.h> |
... | ... | @@ -860,6 +861,8 @@ |
860 | 861 | err = exec_permission_lite(inode); |
861 | 862 | if (err == -EAGAIN) |
862 | 863 | err = vfs_permission(nd, MAY_EXEC); |
864 | + if (!err) | |
865 | + err = ima_path_check(&nd->path, MAY_EXEC); | |
863 | 866 | if (err) |
864 | 867 | break; |
865 | 868 | |
... | ... | @@ -1523,6 +1526,11 @@ |
1523 | 1526 | } |
1524 | 1527 | |
1525 | 1528 | error = vfs_permission(nd, acc_mode); |
1529 | + if (error) | |
1530 | + return error; | |
1531 | + | |
1532 | + error = ima_path_check(&nd->path, | |
1533 | + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); | |
1526 | 1534 | if (error) |
1527 | 1535 | return error; |
1528 | 1536 | /* |
include/linux/ima.h
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 | + | |
15 | +static inline int ima_bprm_check(struct linux_binprm *bprm) | |
16 | +{ | |
17 | + return 0; | |
18 | +} | |
19 | + | |
20 | +static inline int ima_inode_alloc(struct inode *inode) | |
21 | +{ | |
22 | + return 0; | |
23 | +} | |
24 | + | |
25 | +static inline void ima_inode_free(struct inode *inode) | |
26 | +{ | |
27 | + return; | |
28 | +} | |
29 | + | |
30 | +static inline int ima_path_check(struct path *path, int mask) | |
31 | +{ | |
32 | + return 0; | |
33 | +} | |
34 | + | |
35 | +static inline void ima_file_free(struct file *file) | |
36 | +{ | |
37 | + return; | |
38 | +} | |
39 | + | |
40 | +static inline int ima_file_mmap(struct file *file, unsigned long prot) | |
41 | +{ | |
42 | + return 0; | |
43 | +} | |
44 | +#endif /* _LINUX_IMA_H */ |
mm/mmap.c
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | #include <linux/fs.h> |
21 | 21 | #include <linux/personality.h> |
22 | 22 | #include <linux/security.h> |
23 | +#include <linux/ima.h> | |
23 | 24 | #include <linux/hugetlb.h> |
24 | 25 | #include <linux/profile.h> |
25 | 26 | #include <linux/module.h> |
... | ... | @@ -1048,6 +1049,9 @@ |
1048 | 1049 | } |
1049 | 1050 | |
1050 | 1051 | error = security_file_mmap(file, reqprot, prot, flags, addr, 0); |
1052 | + if (error) | |
1053 | + return error; | |
1054 | + error = ima_file_mmap(file, prot); | |
1051 | 1055 | if (error) |
1052 | 1056 | return error; |
1053 | 1057 |