summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2012-09-11 23:16:37 -0400
committerJames Morris <james.l.morris@oracle.com>2012-09-11 23:16:37 -0400
commit9ddf6aa8cbc07764c7fe33cfdb8644ca5e828252 (patch)
treed0796f172c096147e1a7c0337279bf7dca6f13f2
parentb25b09ecf98bf6a32f3732281c2db13be6aeb14c (diff)
parent8606404fa555c2ee691376fcc640ab89fe752035 (diff)
Merge branch 'next-ima-appraisal' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
As requested by Mimi, this adds the IMA Appraisal feature.
-rw-r--r--Documentation/ABI/testing/ima_policy25
-rw-r--r--Documentation/kernel-parameters.txt8
-rw-r--r--fs/attr.c2
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/xattr.c6
-rw-r--r--include/linux/ima.h27
-rw-r--r--include/linux/integrity.h7
-rw-r--r--include/linux/xattr.h3
-rw-r--r--security/integrity/evm/evm_main.c3
-rw-r--r--security/integrity/iint.c64
-rw-r--r--security/integrity/ima/Kconfig15
-rw-r--r--security/integrity/ima/Makefile1
-rw-r--r--security/integrity/ima/ima.h37
-rw-r--r--security/integrity/ima/ima_api.c56
-rw-r--r--security/integrity/ima/ima_appraise.c263
-rw-r--r--security/integrity/ima/ima_crypto.c8
-rw-r--r--security/integrity/ima/ima_main.c90
-rw-r--r--security/integrity/ima/ima_policy.c183
-rw-r--r--security/integrity/integrity.h11
-rw-r--r--security/security.c6
20 files changed, 668 insertions, 149 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
index 6cd6daefaaed..dcff82205477 100644
--- a/Documentation/ABI/testing/ima_policy
+++ b/Documentation/ABI/testing/ima_policy
@@ -12,11 +12,14 @@ Description:
12 then closing the file. The new policy takes effect after 12 then closing the file. The new policy takes effect after
13 the file ima/policy is closed. 13 the file ima/policy is closed.
14 14
15 IMA appraisal, if configured, uses these file measurements
16 for local measurement appraisal.
17
15 rule format: action [condition ...] 18 rule format: action [condition ...]
16 19
17 action: measure | dont_measure 20 action: measure | dont_measure | appraise | dont_appraise
18 condition:= base | lsm 21 condition:= base | lsm
19 base: [[func=] [mask=] [fsmagic=] [uid=]] 22 base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
20 lsm: [[subj_user=] [subj_role=] [subj_type=] 23 lsm: [[subj_user=] [subj_role=] [subj_type=]
21 [obj_user=] [obj_role=] [obj_type=]] 24 [obj_user=] [obj_role=] [obj_type=]]
22 25
@@ -24,36 +27,50 @@ Description:
24 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] 27 mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
25 fsmagic:= hex value 28 fsmagic:= hex value
26 uid:= decimal value 29 uid:= decimal value
30 fowner:=decimal value
27 lsm: are LSM specific 31 lsm: are LSM specific
28 32
29 default policy: 33 default policy:
30 # PROC_SUPER_MAGIC 34 # PROC_SUPER_MAGIC
31 dont_measure fsmagic=0x9fa0 35 dont_measure fsmagic=0x9fa0
36 dont_appraise fsmagic=0x9fa0
32 # SYSFS_MAGIC 37 # SYSFS_MAGIC
33 dont_measure fsmagic=0x62656572 38 dont_measure fsmagic=0x62656572
39 dont_appraise fsmagic=0x62656572
34 # DEBUGFS_MAGIC 40 # DEBUGFS_MAGIC
35 dont_measure fsmagic=0x64626720 41 dont_measure fsmagic=0x64626720
42 dont_appraise fsmagic=0x64626720
36 # TMPFS_MAGIC 43 # TMPFS_MAGIC
37 dont_measure fsmagic=0x01021994 44 dont_measure fsmagic=0x01021994
45 dont_appraise fsmagic=0x01021994
46 # RAMFS_MAGIC
47 dont_measure fsmagic=0x858458f6
48 dont_appraise fsmagic=0x858458f6
38 # SECURITYFS_MAGIC 49 # SECURITYFS_MAGIC
39 dont_measure fsmagic=0x73636673 50 dont_measure fsmagic=0x73636673
51 dont_appraise fsmagic=0x73636673
40 52
41 measure func=BPRM_CHECK 53 measure func=BPRM_CHECK
42 measure func=FILE_MMAP mask=MAY_EXEC 54 measure func=FILE_MMAP mask=MAY_EXEC
43 measure func=FILE_CHECK mask=MAY_READ uid=0 55 measure func=FILE_CHECK mask=MAY_READ uid=0
56 appraise fowner=0
44 57
45 The default policy measures all executables in bprm_check, 58 The default policy measures all executables in bprm_check,
46 all files mmapped executable in file_mmap, and all files 59 all files mmapped executable in file_mmap, and all files
47 open for read by root in do_filp_open. 60 open for read by root in do_filp_open. The default appraisal
61 policy appraises all files owned by root.
48 62
49 Examples of LSM specific definitions: 63 Examples of LSM specific definitions:
50 64
51 SELinux: 65 SELinux:
52 # SELINUX_MAGIC 66 # SELINUX_MAGIC
53 dont_measure fsmagic=0xF97CFF8C 67 dont_measure fsmagic=0xf97cff8c
68 dont_appraise fsmagic=0xf97cff8c
54 69
55 dont_measure obj_type=var_log_t 70 dont_measure obj_type=var_log_t
71 dont_appraise obj_type=var_log_t
56 dont_measure obj_type=auditd_log_t 72 dont_measure obj_type=auditd_log_t
73 dont_appraise obj_type=auditd_log_t
57 measure subj_user=system_u func=FILE_CHECK mask=MAY_READ 74 measure subj_user=system_u func=FILE_CHECK mask=MAY_READ
58 measure subj_role=system_r func=FILE_CHECK mask=MAY_READ 75 measure subj_role=system_r func=FILE_CHECK mask=MAY_READ
59 76
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ad7e2e5088c1..949dddcfd177 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1051,6 +1051,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1051 ihash_entries= [KNL] 1051 ihash_entries= [KNL]
1052 Set number of hash buckets for inode cache. 1052 Set number of hash buckets for inode cache.
1053 1053
1054 ima_appraise= [IMA] appraise integrity measurements
1055 Format: { "off" | "enforce" | "fix" }
1056 default: "enforce"
1057
1058 ima_appraise_tcb [IMA]
1059 The builtin appraise policy appraises all files
1060 owned by uid=0.
1061
1054 ima_audit= [IMA] 1062 ima_audit= [IMA]
1055 Format: { "0" | "1" } 1063 Format: { "0" | "1" }
1056 0 -- integrity auditing messages. (Default) 1064 0 -- integrity auditing messages. (Default)
diff --git a/fs/attr.c b/fs/attr.c
index 29e38a1f7f77..cce7df53b694 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -14,6 +14,7 @@
14#include <linux/fcntl.h> 14#include <linux/fcntl.h>
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/evm.h> 16#include <linux/evm.h>
17#include <linux/ima.h>
17 18
18/** 19/**
19 * inode_change_ok - check if attribute changes to an inode are allowed 20 * inode_change_ok - check if attribute changes to an inode are allowed
@@ -247,6 +248,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
247 248
248 if (!error) { 249 if (!error) {
249 fsnotify_change(dentry, ia_valid); 250 fsnotify_change(dentry, ia_valid);
251 ima_inode_post_setattr(dentry);
250 evm_inode_post_setattr(dentry, ia_valid); 252 evm_inode_post_setattr(dentry, ia_valid);
251 } 253 }
252 254
diff --git a/fs/file_table.c b/fs/file_table.c
index 701985e4ccda..a41f23f90b17 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -243,10 +243,10 @@ static void __fput(struct file *file)
243 if (file->f_op && file->f_op->fasync) 243 if (file->f_op && file->f_op->fasync)
244 file->f_op->fasync(-1, file, 0); 244 file->f_op->fasync(-1, file, 0);
245 } 245 }
246 ima_file_free(file);
246 if (file->f_op && file->f_op->release) 247 if (file->f_op && file->f_op->release)
247 file->f_op->release(inode, file); 248 file->f_op->release(inode, file);
248 security_file_free(file); 249 security_file_free(file);
249 ima_file_free(file);
250 if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL && 250 if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL &&
251 !(file->f_mode & FMODE_PATH))) { 251 !(file->f_mode & FMODE_PATH))) {
252 cdev_put(inode->i_cdev); 252 cdev_put(inode->i_cdev);
diff --git a/fs/xattr.c b/fs/xattr.c
index 4d45b7189e7e..107f457143c3 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -295,11 +295,13 @@ vfs_removexattr(struct dentry *dentry, const char *name)
295 if (error) 295 if (error)
296 return error; 296 return error;
297 297
298 mutex_lock(&inode->i_mutex);
298 error = security_inode_removexattr(dentry, name); 299 error = security_inode_removexattr(dentry, name);
299 if (error) 300 if (error) {
301 mutex_unlock(&inode->i_mutex);
300 return error; 302 return error;
303 }
301 304
302 mutex_lock(&inode->i_mutex);
303 error = inode->i_op->removexattr(dentry, name); 305 error = inode->i_op->removexattr(dentry, name);
304 mutex_unlock(&inode->i_mutex); 306 mutex_unlock(&inode->i_mutex);
305 307
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 6ac8e50c6cf5..2c7223d7e73b 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -39,5 +39,32 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot)
39{ 39{
40 return 0; 40 return 0;
41} 41}
42
42#endif /* CONFIG_IMA_H */ 43#endif /* CONFIG_IMA_H */
44
45#ifdef CONFIG_IMA_APPRAISE
46extern void ima_inode_post_setattr(struct dentry *dentry);
47extern int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
48 const void *xattr_value, size_t xattr_value_len);
49extern int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name);
50#else
51static inline void ima_inode_post_setattr(struct dentry *dentry)
52{
53 return;
54}
55
56static inline int ima_inode_setxattr(struct dentry *dentry,
57 const char *xattr_name,
58 const void *xattr_value,
59 size_t xattr_value_len)
60{
61 return 0;
62}
63
64static inline int ima_inode_removexattr(struct dentry *dentry,
65 const char *xattr_name)
66{
67 return 0;
68}
69#endif /* CONFIG_IMA_APPRAISE_H */
43#endif /* _LINUX_IMA_H */ 70#endif /* _LINUX_IMA_H */
diff --git a/include/linux/integrity.h b/include/linux/integrity.h
index a0c41256cb92..66c5fe9550a5 100644
--- a/include/linux/integrity.h
+++ b/include/linux/integrity.h
@@ -22,13 +22,14 @@ enum integrity_status {
22 22
23/* List of EVM protected security xattrs */ 23/* List of EVM protected security xattrs */
24#ifdef CONFIG_INTEGRITY 24#ifdef CONFIG_INTEGRITY
25extern int integrity_inode_alloc(struct inode *inode); 25extern struct integrity_iint_cache *integrity_inode_get(struct inode *inode);
26extern void integrity_inode_free(struct inode *inode); 26extern void integrity_inode_free(struct inode *inode);
27 27
28#else 28#else
29static inline int integrity_inode_alloc(struct inode *inode) 29static inline struct integrity_iint_cache *
30 integrity_inode_get(struct inode *inode)
30{ 31{
31 return 0; 32 return NULL;
32} 33}
33 34
34static inline void integrity_inode_free(struct inode *inode) 35static inline void integrity_inode_free(struct inode *inode)
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index e5d122031542..77a3e686d566 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -33,6 +33,9 @@
33#define XATTR_EVM_SUFFIX "evm" 33#define XATTR_EVM_SUFFIX "evm"
34#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX 34#define XATTR_NAME_EVM XATTR_SECURITY_PREFIX XATTR_EVM_SUFFIX
35 35
36#define XATTR_IMA_SUFFIX "ima"
37#define XATTR_NAME_IMA XATTR_SECURITY_PREFIX XATTR_IMA_SUFFIX
38
36#define XATTR_SELINUX_SUFFIX "selinux" 39#define XATTR_SELINUX_SUFFIX "selinux"
37#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 40#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
38 41
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 8901501425f4..eb5484504f50 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -34,6 +34,9 @@ char *evm_config_xattrnames[] = {
34#ifdef CONFIG_SECURITY_SMACK 34#ifdef CONFIG_SECURITY_SMACK
35 XATTR_NAME_SMACK, 35 XATTR_NAME_SMACK,
36#endif 36#endif
37#ifdef CONFIG_IMA_APPRAISE
38 XATTR_NAME_IMA,
39#endif
37 XATTR_NAME_CAPS, 40 XATTR_NAME_CAPS,
38 NULL 41 NULL
39}; 42};
diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 399641c3e846..d82a5a13d855 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -22,7 +22,7 @@
22#include "integrity.h" 22#include "integrity.h"
23 23
24static struct rb_root integrity_iint_tree = RB_ROOT; 24static struct rb_root integrity_iint_tree = RB_ROOT;
25static DEFINE_SPINLOCK(integrity_iint_lock); 25static DEFINE_RWLOCK(integrity_iint_lock);
26static struct kmem_cache *iint_cache __read_mostly; 26static struct kmem_cache *iint_cache __read_mostly;
27 27
28int iint_initialized; 28int iint_initialized;
@@ -35,8 +35,6 @@ static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
35 struct integrity_iint_cache *iint; 35 struct integrity_iint_cache *iint;
36 struct rb_node *n = integrity_iint_tree.rb_node; 36 struct rb_node *n = integrity_iint_tree.rb_node;
37 37
38 assert_spin_locked(&integrity_iint_lock);
39
40 while (n) { 38 while (n) {
41 iint = rb_entry(n, struct integrity_iint_cache, rb_node); 39 iint = rb_entry(n, struct integrity_iint_cache, rb_node);
42 40
@@ -63,9 +61,9 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
63 if (!IS_IMA(inode)) 61 if (!IS_IMA(inode))
64 return NULL; 62 return NULL;
65 63
66 spin_lock(&integrity_iint_lock); 64 read_lock(&integrity_iint_lock);
67 iint = __integrity_iint_find(inode); 65 iint = __integrity_iint_find(inode);
68 spin_unlock(&integrity_iint_lock); 66 read_unlock(&integrity_iint_lock);
69 67
70 return iint; 68 return iint;
71} 69}
@@ -74,59 +72,53 @@ static void iint_free(struct integrity_iint_cache *iint)
74{ 72{
75 iint->version = 0; 73 iint->version = 0;
76 iint->flags = 0UL; 74 iint->flags = 0UL;
75 iint->ima_status = INTEGRITY_UNKNOWN;
77 iint->evm_status = INTEGRITY_UNKNOWN; 76 iint->evm_status = INTEGRITY_UNKNOWN;
78 kmem_cache_free(iint_cache, iint); 77 kmem_cache_free(iint_cache, iint);
79} 78}
80 79
81/** 80/**
82 * integrity_inode_alloc - allocate an iint associated with an inode 81 * integrity_inode_get - find or allocate an iint associated with an inode
83 * @inode: pointer to the inode 82 * @inode: pointer to the inode
83 * @return: allocated iint
84 *
85 * Caller must lock i_mutex
84 */ 86 */
85int integrity_inode_alloc(struct inode *inode) 87struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
86{ 88{
87 struct rb_node **p; 89 struct rb_node **p;
88 struct rb_node *new_node, *parent = NULL; 90 struct rb_node *node, *parent = NULL;
89 struct integrity_iint_cache *new_iint, *test_iint; 91 struct integrity_iint_cache *iint, *test_iint;
90 int rc;
91 92
92 new_iint = kmem_cache_alloc(iint_cache, GFP_NOFS); 93 iint = integrity_iint_find(inode);
93 if (!new_iint) 94 if (iint)
94 return -ENOMEM; 95 return iint;
95 96
96 new_iint->inode = inode; 97 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
97 new_node = &new_iint->rb_node; 98 if (!iint)
99 return NULL;
98 100
99 mutex_lock(&inode->i_mutex); /* i_flags */ 101 write_lock(&integrity_iint_lock);
100 spin_lock(&integrity_iint_lock);
101 102
102 p = &integrity_iint_tree.rb_node; 103 p = &integrity_iint_tree.rb_node;
103 while (*p) { 104 while (*p) {
104 parent = *p; 105 parent = *p;
105 test_iint = rb_entry(parent, struct integrity_iint_cache, 106 test_iint = rb_entry(parent, struct integrity_iint_cache,
106 rb_node); 107 rb_node);
107 rc = -EEXIST;
108 if (inode < test_iint->inode) 108 if (inode < test_iint->inode)
109 p = &(*p)->rb_left; 109 p = &(*p)->rb_left;
110 else if (inode > test_iint->inode)
111 p = &(*p)->rb_right;
112 else 110 else
113 goto out_err; 111 p = &(*p)->rb_right;
114 } 112 }
115 113
114 iint->inode = inode;
115 node = &iint->rb_node;
116 inode->i_flags |= S_IMA; 116 inode->i_flags |= S_IMA;
117 rb_link_node(new_node, parent, p); 117 rb_link_node(node, parent, p);
118 rb_insert_color(new_node, &integrity_iint_tree); 118 rb_insert_color(node, &integrity_iint_tree);
119 119
120 spin_unlock(&integrity_iint_lock); 120 write_unlock(&integrity_iint_lock);
121 mutex_unlock(&inode->i_mutex); /* i_flags */ 121 return iint;
122
123 return 0;
124out_err:
125 spin_unlock(&integrity_iint_lock);
126 mutex_unlock(&inode->i_mutex); /* i_flags */
127 iint_free(new_iint);
128
129 return rc;
130} 122}
131 123
132/** 124/**
@@ -142,10 +134,10 @@ void integrity_inode_free(struct inode *inode)
142 if (!IS_IMA(inode)) 134 if (!IS_IMA(inode))
143 return; 135 return;
144 136
145 spin_lock(&integrity_iint_lock); 137 write_lock(&integrity_iint_lock);
146 iint = __integrity_iint_find(inode); 138 iint = __integrity_iint_find(inode);
147 rb_erase(&iint->rb_node, &integrity_iint_tree); 139 rb_erase(&iint->rb_node, &integrity_iint_tree);
148 spin_unlock(&integrity_iint_lock); 140 write_unlock(&integrity_iint_lock);
149 141
150 iint_free(iint); 142 iint_free(iint);
151} 143}
@@ -157,7 +149,7 @@ static void init_once(void *foo)
157 memset(iint, 0, sizeof *iint); 149 memset(iint, 0, sizeof *iint);
158 iint->version = 0; 150 iint->version = 0;
159 iint->flags = 0UL; 151 iint->flags = 0UL;
160 mutex_init(&iint->mutex); 152 iint->ima_status = INTEGRITY_UNKNOWN;
161 iint->evm_status = INTEGRITY_UNKNOWN; 153 iint->evm_status = INTEGRITY_UNKNOWN;
162} 154}
163 155
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 809ccf19d09c..d232c73647ae 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -56,3 +56,18 @@ config IMA_LSM_RULES
56 default y 56 default y
57 help 57 help
58 Disabling this option will disregard LSM based policy rules. 58 Disabling this option will disregard LSM based policy rules.
59
60config IMA_APPRAISE
61 bool "Appraise integrity measurements"
62 depends on IMA
63 default n
64 help
65 This option enables local measurement integrity appraisal.
66 It requires the system to be labeled with a security extended
67 attribute containing the file hash measurement. To protect
68 the security extended attributes from offline attack, enable
69 and configure EVM.
70
71 For more information on integrity appraisal refer to:
72 <http://linux-ima.sourceforge.net>
73 If unsure, say N.
diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile
index 5f740f6971e1..3f2ca6bdc384 100644
--- a/security/integrity/ima/Makefile
+++ b/security/integrity/ima/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_IMA) += ima.o
8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ 8ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \
9 ima_policy.o 9 ima_policy.o
10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o 10ima-$(CONFIG_IMA_AUDIT) += ima_audit.o
11ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index e7c99fd0d223..069a4aa63e95 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -40,6 +40,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
40extern int ima_initialized; 40extern int ima_initialized;
41extern int ima_used_chip; 41extern int ima_used_chip;
42extern char *ima_hash; 42extern char *ima_hash;
43extern int ima_appraise;
43 44
44/* IMA inode template definition */ 45/* IMA inode template definition */
45struct ima_template_data { 46struct ima_template_data {
@@ -107,6 +108,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
107} 108}
108 109
109/* LIM API function definitions */ 110/* LIM API function definitions */
111int ima_must_appraise_or_measure(struct inode *inode, int mask, int function);
110int ima_must_measure(struct inode *inode, int mask, int function); 112int ima_must_measure(struct inode *inode, int mask, int function);
111int ima_collect_measurement(struct integrity_iint_cache *iint, 113int ima_collect_measurement(struct integrity_iint_cache *iint,
112 struct file *file); 114 struct file *file);
@@ -123,14 +125,45 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
123struct integrity_iint_cache *integrity_iint_find(struct inode *inode); 125struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
124 126
125/* IMA policy related functions */ 127/* IMA policy related functions */
126enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 128enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR };
127 129
128int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); 130int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
131 int flags);
129void ima_init_policy(void); 132void ima_init_policy(void);
130void ima_update_policy(void); 133void ima_update_policy(void);
131ssize_t ima_parse_add_rule(char *); 134ssize_t ima_parse_add_rule(char *);
132void ima_delete_rules(void); 135void ima_delete_rules(void);
133 136
137/* Appraise integrity measurements */
138#define IMA_APPRAISE_ENFORCE 0x01
139#define IMA_APPRAISE_FIX 0x02
140
141#ifdef CONFIG_IMA_APPRAISE
142int ima_appraise_measurement(struct integrity_iint_cache *iint,
143 struct file *file, const unsigned char *filename);
144int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask);
145void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
146
147#else
148static inline int ima_appraise_measurement(struct integrity_iint_cache *iint,
149 struct file *file,
150 const unsigned char *filename)
151{
152 return INTEGRITY_UNKNOWN;
153}
154
155static inline int ima_must_appraise(struct inode *inode,
156 enum ima_hooks func, int mask)
157{
158 return 0;
159}
160
161static inline void ima_update_xattr(struct integrity_iint_cache *iint,
162 struct file *file)
163{
164}
165#endif
166
134/* LSM based policy rules require audit */ 167/* LSM based policy rules require audit */
135#ifdef CONFIG_IMA_LSM_RULES 168#ifdef CONFIG_IMA_LSM_RULES
136 169
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 032ff03ad907..33d46859753a 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -9,13 +9,17 @@
9 * License. 9 * License.
10 * 10 *
11 * File: ima_api.c 11 * File: ima_api.c
12 * Implements must_measure, collect_measurement, store_measurement, 12 * Implements must_appraise_or_measure, collect_measurement,
13 * and store_template. 13 * appraise_measurement, store_measurement and store_template.
14 */ 14 */
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17 17#include <linux/file.h>
18#include <linux/fs.h>
19#include <linux/xattr.h>
20#include <linux/evm.h>
18#include "ima.h" 21#include "ima.h"
22
19static const char *IMA_TEMPLATE_NAME = "ima"; 23static const char *IMA_TEMPLATE_NAME = "ima";
20 24
21/* 25/*
@@ -93,7 +97,7 @@ err_out:
93} 97}
94 98
95/** 99/**
96 * ima_must_measure - measure decision based on policy. 100 * ima_must_appraise_or_measure - appraise & measure decision based on policy.
97 * @inode: pointer to inode to measure 101 * @inode: pointer to inode to measure
98 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 102 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
99 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) 103 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
@@ -105,15 +109,22 @@ err_out:
105 * mask: contains the permission mask 109 * mask: contains the permission mask
106 * fsmagic: hex value 110 * fsmagic: hex value
107 * 111 *
108 * Return 0 to measure. For matching a DONT_MEASURE policy, no policy, 112 * Returns IMA_MEASURE, IMA_APPRAISE mask.
109 * or other error, return an error code. 113 *
110*/ 114 */
111int ima_must_measure(struct inode *inode, int mask, int function) 115int ima_must_appraise_or_measure(struct inode *inode, int mask, int function)
112{ 116{
113 int must_measure; 117 int flags = IMA_MEASURE | IMA_APPRAISE;
118
119 if (!ima_appraise)
120 flags &= ~IMA_APPRAISE;
121
122 return ima_match_policy(inode, function, mask, flags);
123}
114 124
115 must_measure = ima_match_policy(inode, function, mask); 125int ima_must_measure(struct inode *inode, int mask, int function)
116 return must_measure ? 0 : -EACCES; 126{
127 return ima_match_policy(inode, function, mask, IMA_MEASURE);
117} 128}
118 129
119/* 130/*
@@ -129,16 +140,24 @@ int ima_must_measure(struct inode *inode, int mask, int function)
129int ima_collect_measurement(struct integrity_iint_cache *iint, 140int ima_collect_measurement(struct integrity_iint_cache *iint,
130 struct file *file) 141 struct file *file)
131{ 142{
132 int result = -EEXIST; 143 struct inode *inode = file->f_dentry->d_inode;
144 const char *filename = file->f_dentry->d_name.name;
145 int result = 0;
133 146
134 if (!(iint->flags & IMA_MEASURED)) { 147 if (!(iint->flags & IMA_COLLECTED)) {
135 u64 i_version = file->f_dentry->d_inode->i_version; 148 u64 i_version = file->f_dentry->d_inode->i_version;
136 149
137 memset(iint->digest, 0, IMA_DIGEST_SIZE); 150 iint->ima_xattr.type = IMA_XATTR_DIGEST;
138 result = ima_calc_hash(file, iint->digest); 151 result = ima_calc_hash(file, iint->ima_xattr.digest);
139 if (!result) 152 if (!result) {
140 iint->version = i_version; 153 iint->version = i_version;
154 iint->flags |= IMA_COLLECTED;
155 }
141 } 156 }
157 if (result)
158 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
159 filename, "collect_data", "failed",
160 result, 0);
142 return result; 161 return result;
143} 162}
144 163
@@ -167,6 +186,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
167 struct ima_template_entry *entry; 186 struct ima_template_entry *entry;
168 int violation = 0; 187 int violation = 0;
169 188
189 if (iint->flags & IMA_MEASURED)
190 return;
191
170 entry = kmalloc(sizeof(*entry), GFP_KERNEL); 192 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
171 if (!entry) { 193 if (!entry) {
172 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
@@ -174,7 +196,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
174 return; 196 return;
175 } 197 }
176 memset(&entry->template, 0, sizeof(entry->template)); 198 memset(&entry->template, 0, sizeof(entry->template));
177 memcpy(entry->template.digest, iint->digest, IMA_DIGEST_SIZE); 199 memcpy(entry->template.digest, iint->ima_xattr.digest, IMA_DIGEST_SIZE);
178 strcpy(entry->template.file_name, 200 strcpy(entry->template.file_name,
179 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ? 201 (strlen(filename) > IMA_EVENT_NAME_LEN_MAX) ?
180 file->f_dentry->d_name.name : filename); 202 file->f_dentry->d_name.name : filename);
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
new file mode 100644
index 000000000000..4cdf36ad884a
--- /dev/null
+++ b/security/integrity/ima/ima_appraise.c
@@ -0,0 +1,263 @@
1/*
2 * Copyright (C) 2011 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 */
11#include <linux/module.h>
12#include <linux/file.h>
13#include <linux/fs.h>
14#include <linux/xattr.h>
15#include <linux/magic.h>
16#include <linux/ima.h>
17#include <linux/evm.h>
18
19#include "ima.h"
20
21static int __init default_appraise_setup(char *str)
22{
23 if (strncmp(str, "off", 3) == 0)
24 ima_appraise = 0;
25 else if (strncmp(str, "fix", 3) == 0)
26 ima_appraise = IMA_APPRAISE_FIX;
27 return 1;
28}
29
30__setup("ima_appraise=", default_appraise_setup);
31
32/*
33 * ima_must_appraise - set appraise flag
34 *
35 * Return 1 to appraise
36 */
37int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask)
38{
39 if (!ima_appraise)
40 return 0;
41
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
43}
44
45static void ima_fix_xattr(struct dentry *dentry,
46 struct integrity_iint_cache *iint)
47{
48 iint->ima_xattr.type = IMA_XATTR_DIGEST;
49 __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, (u8 *)&iint->ima_xattr,
50 sizeof iint->ima_xattr, 0);
51}
52
53/*
54 * ima_appraise_measurement - appraise file measurement
55 *
56 * Call evm_verifyxattr() to verify the integrity of 'security.ima'.
57 * Assuming success, compare the xattr hash with the collected measurement.
58 *
59 * Return 0 on success, error code otherwise
60 */
61int ima_appraise_measurement(struct integrity_iint_cache *iint,
62 struct file *file, const unsigned char *filename)
63{
64 struct dentry *dentry = file->f_dentry;
65 struct inode *inode = dentry->d_inode;
66 struct evm_ima_xattr_data *xattr_value = NULL;
67 enum integrity_status status = INTEGRITY_UNKNOWN;
68 const char *op = "appraise_data";
69 char *cause = "unknown";
70 int rc;
71
72 if (!ima_appraise)
73 return 0;
74 if (!inode->i_op->getxattr)
75 return INTEGRITY_UNKNOWN;
76
77 if (iint->flags & IMA_APPRAISED)
78 return iint->ima_status;
79
80 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
81 0, GFP_NOFS);
82 if (rc <= 0) {
83 if (rc && rc != -ENODATA)
84 goto out;
85
86 cause = "missing-hash";
87 status =
88 (inode->i_size == 0) ? INTEGRITY_PASS : INTEGRITY_NOLABEL;
89 goto out;
90 }
91
92 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
93 if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) {
94 if ((status == INTEGRITY_NOLABEL)
95 || (status == INTEGRITY_NOXATTRS))
96 cause = "missing-HMAC";
97 else if (status == INTEGRITY_FAIL)
98 cause = "invalid-HMAC";
99 goto out;
100 }
101
102 switch (xattr_value->type) {
103 case IMA_XATTR_DIGEST:
104 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
105 IMA_DIGEST_SIZE);
106 if (rc) {
107 cause = "invalid-hash";
108 status = INTEGRITY_FAIL;
109 print_hex_dump_bytes("security.ima: ", DUMP_PREFIX_NONE,
110 xattr_value, sizeof(*xattr_value));
111 print_hex_dump_bytes("collected: ", DUMP_PREFIX_NONE,
112 (u8 *)&iint->ima_xattr,
113 sizeof iint->ima_xattr);
114 break;
115 }
116 status = INTEGRITY_PASS;
117 break;
118 case EVM_IMA_XATTR_DIGSIG:
119 iint->flags |= IMA_DIGSIG;
120 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
121 xattr_value->digest, rc - 1,
122 iint->ima_xattr.digest,
123 IMA_DIGEST_SIZE);
124 if (rc == -EOPNOTSUPP) {
125 status = INTEGRITY_UNKNOWN;
126 } else if (rc) {
127 cause = "invalid-signature";
128 status = INTEGRITY_FAIL;
129 } else {
130 status = INTEGRITY_PASS;
131 }
132 break;
133 default:
134 status = INTEGRITY_UNKNOWN;
135 cause = "unknown-ima-data";
136 break;
137 }
138
139out:
140 if (status != INTEGRITY_PASS) {
141 if ((ima_appraise & IMA_APPRAISE_FIX) &&
142 (!xattr_value ||
143 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
144 ima_fix_xattr(dentry, iint);
145 status = INTEGRITY_PASS;
146 }
147 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
148 op, cause, rc, 0);
149 } else {
150 iint->flags |= IMA_APPRAISED;
151 }
152 iint->ima_status = status;
153 kfree(xattr_value);
154 return status;
155}
156
157/*
158 * ima_update_xattr - update 'security.ima' hash value
159 */
160void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
161{
162 struct dentry *dentry = file->f_dentry;
163 int rc = 0;
164
165 /* do not collect and update hash for digital signatures */
166 if (iint->flags & IMA_DIGSIG)
167 return;
168
169 rc = ima_collect_measurement(iint, file);
170 if (rc < 0)
171 return;
172
173 ima_fix_xattr(dentry, iint);
174}
175
176/**
177 * ima_inode_post_setattr - reflect file metadata changes
178 * @dentry: pointer to the affected dentry
179 *
180 * Changes to a dentry's metadata might result in needing to appraise.
181 *
182 * This function is called from notify_change(), which expects the caller
183 * to lock the inode's i_mutex.
184 */
185void ima_inode_post_setattr(struct dentry *dentry)
186{
187 struct inode *inode = dentry->d_inode;
188 struct integrity_iint_cache *iint;
189 int must_appraise, rc;
190
191 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)
192 || !inode->i_op->removexattr)
193 return;
194
195 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
196 iint = integrity_iint_find(inode);
197 if (iint) {
198 if (must_appraise)
199 iint->flags |= IMA_APPRAISE;
200 else
201 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED);
202 }
203 if (!must_appraise)
204 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);
205 return;
206}
207
208/*
209 * ima_protect_xattr - protect 'security.ima'
210 *
211 * Ensure that not just anyone can modify or remove 'security.ima'.
212 */
213static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name,
214 const void *xattr_value, size_t xattr_value_len)
215{
216 if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) {
217 if (!capable(CAP_SYS_ADMIN))
218 return -EPERM;
219 return 1;
220 }
221 return 0;
222}
223
224static void ima_reset_appraise_flags(struct inode *inode)
225{
226 struct integrity_iint_cache *iint;
227
228 if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode))
229 return;
230
231 iint = integrity_iint_find(inode);
232 if (!iint)
233 return;
234
235 iint->flags &= ~(IMA_COLLECTED | IMA_APPRAISED | IMA_MEASURED);
236 return;
237}
238
239int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
240 const void *xattr_value, size_t xattr_value_len)
241{
242 int result;
243
244 result = ima_protect_xattr(dentry, xattr_name, xattr_value,
245 xattr_value_len);
246 if (result == 1) {
247 ima_reset_appraise_flags(dentry->d_inode);
248 result = 0;
249 }
250 return result;
251}
252
253int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name)
254{
255 int result;
256
257 result = ima_protect_xattr(dentry, xattr_name, NULL, 0);
258 if (result == 1) {
259 ima_reset_appraise_flags(dentry->d_inode);
260 result = 0;
261 }
262 return result;
263}
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 9b3ade7468b2..b21ee5b5495a 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -48,7 +48,7 @@ int ima_calc_hash(struct file *file, char *digest)
48 struct scatterlist sg[1]; 48 struct scatterlist sg[1];
49 loff_t i_size, offset = 0; 49 loff_t i_size, offset = 0;
50 char *rbuf; 50 char *rbuf;
51 int rc; 51 int rc, read = 0;
52 52
53 rc = init_desc(&desc); 53 rc = init_desc(&desc);
54 if (rc != 0) 54 if (rc != 0)
@@ -59,6 +59,10 @@ int ima_calc_hash(struct file *file, char *digest)
59 rc = -ENOMEM; 59 rc = -ENOMEM;
60 goto out; 60 goto out;
61 } 61 }
62 if (!(file->f_mode & FMODE_READ)) {
63 file->f_mode |= FMODE_READ;
64 read = 1;
65 }
62 i_size = i_size_read(file->f_dentry->d_inode); 66 i_size = i_size_read(file->f_dentry->d_inode);
63 while (offset < i_size) { 67 while (offset < i_size) {
64 int rbuf_len; 68 int rbuf_len;
@@ -80,6 +84,8 @@ int ima_calc_hash(struct file *file, char *digest)
80 kfree(rbuf); 84 kfree(rbuf);
81 if (!rc) 85 if (!rc)
82 rc = crypto_hash_final(&desc, digest); 86 rc = crypto_hash_final(&desc, digest);
87 if (read)
88 file->f_mode &= ~FMODE_READ;
83out: 89out:
84 crypto_free_hash(desc.tfm); 90 crypto_free_hash(desc.tfm);
85 return rc; 91 return rc;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index be8294915cf7..df6521296051 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -22,12 +22,19 @@
22#include <linux/mount.h> 22#include <linux/mount.h>
23#include <linux/mman.h> 23#include <linux/mman.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/xattr.h>
25#include <linux/ima.h> 26#include <linux/ima.h>
26 27
27#include "ima.h" 28#include "ima.h"
28 29
29int ima_initialized; 30int ima_initialized;
30 31
32#ifdef CONFIG_IMA_APPRAISE
33int ima_appraise = IMA_APPRAISE_ENFORCE;
34#else
35int ima_appraise;
36#endif
37
31char *ima_hash = "sha1"; 38char *ima_hash = "sha1";
32static int __init hash_setup(char *str) 39static int __init hash_setup(char *str)
33{ 40{
@@ -52,7 +59,7 @@ static void ima_rdwr_violation_check(struct file *file)
52 struct dentry *dentry = file->f_path.dentry; 59 struct dentry *dentry = file->f_path.dentry;
53 struct inode *inode = dentry->d_inode; 60 struct inode *inode = dentry->d_inode;
54 fmode_t mode = file->f_mode; 61 fmode_t mode = file->f_mode;
55 int rc; 62 int must_measure;
56 bool send_tomtou = false, send_writers = false; 63 bool send_tomtou = false, send_writers = false;
57 unsigned char *pathname = NULL, *pathbuf = NULL; 64 unsigned char *pathname = NULL, *pathbuf = NULL;
58 65
@@ -67,8 +74,8 @@ static void ima_rdwr_violation_check(struct file *file)
67 goto out; 74 goto out;
68 } 75 }
69 76
70 rc = ima_must_measure(inode, MAY_READ, FILE_CHECK); 77 must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK);
71 if (rc < 0) 78 if (!must_measure)
72 goto out; 79 goto out;
73 80
74 if (atomic_read(&inode->i_writecount) > 0) 81 if (atomic_read(&inode->i_writecount) > 0)
@@ -100,17 +107,21 @@ out:
100} 107}
101 108
102static void ima_check_last_writer(struct integrity_iint_cache *iint, 109static void ima_check_last_writer(struct integrity_iint_cache *iint,
103 struct inode *inode, 110 struct inode *inode, struct file *file)
104 struct file *file)
105{ 111{
106 fmode_t mode = file->f_mode; 112 fmode_t mode = file->f_mode;
107 113
108 mutex_lock(&iint->mutex); 114 if (!(mode & FMODE_WRITE))
109 if (mode & FMODE_WRITE && 115 return;
110 atomic_read(&inode->i_writecount) == 1 && 116
111 iint->version != inode->i_version) 117 mutex_lock(&inode->i_mutex);
112 iint->flags &= ~IMA_MEASURED; 118 if (atomic_read(&inode->i_writecount) == 1 &&
113 mutex_unlock(&iint->mutex); 119 iint->version != inode->i_version) {
120 iint->flags &= ~(IMA_COLLECTED | IMA_APPRAISED | IMA_MEASURED);
121 if (iint->flags & IMA_APPRAISE)
122 ima_update_xattr(iint, file);
123 }
124 mutex_unlock(&inode->i_mutex);
114} 125}
115 126
116/** 127/**
@@ -140,28 +151,36 @@ static int process_measurement(struct file *file, const unsigned char *filename,
140 struct inode *inode = file->f_dentry->d_inode; 151 struct inode *inode = file->f_dentry->d_inode;
141 struct integrity_iint_cache *iint; 152 struct integrity_iint_cache *iint;
142 unsigned char *pathname = NULL, *pathbuf = NULL; 153 unsigned char *pathname = NULL, *pathbuf = NULL;
143 int rc = 0; 154 int rc = -ENOMEM, action, must_appraise;
144 155
145 if (!ima_initialized || !S_ISREG(inode->i_mode)) 156 if (!ima_initialized || !S_ISREG(inode->i_mode))
146 return 0; 157 return 0;
147 158
148 rc = ima_must_measure(inode, mask, function); 159 /* Determine if in appraise/measurement policy,
149 if (rc != 0) 160 * returns IMA_MEASURE, IMA_APPRAISE bitmask. */
150 return rc; 161 action = ima_must_appraise_or_measure(inode, mask, function);
151retry: 162 if (!action)
152 iint = integrity_iint_find(inode); 163 return 0;
153 if (!iint) {
154 rc = integrity_inode_alloc(inode);
155 if (!rc || rc == -EEXIST)
156 goto retry;
157 return rc;
158 }
159 164
160 mutex_lock(&iint->mutex); 165 must_appraise = action & IMA_APPRAISE;
161 166
162 rc = iint->flags & IMA_MEASURED ? 1 : 0; 167 mutex_lock(&inode->i_mutex);
163 if (rc != 0) 168
169 iint = integrity_inode_get(inode);
170 if (!iint)
171 goto out;
172
173 /* Determine if already appraised/measured based on bitmask
174 * (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED) */
175 iint->flags |= action;
176 action &= ~((iint->flags & (IMA_MEASURED | IMA_APPRAISED)) >> 1);
177
178 /* Nothing to do, just return existing appraised status */
179 if (!action) {
180 if (iint->flags & IMA_APPRAISED)
181 rc = iint->ima_status;
164 goto out; 182 goto out;
183 }
165 184
166 rc = ima_collect_measurement(iint, file); 185 rc = ima_collect_measurement(iint, file);
167 if (rc != 0) 186 if (rc != 0)
@@ -177,11 +196,16 @@ retry:
177 pathname = NULL; 196 pathname = NULL;
178 } 197 }
179 } 198 }
180 ima_store_measurement(iint, file, !pathname ? filename : pathname); 199 if (action & IMA_MEASURE)
200 ima_store_measurement(iint, file,
201 !pathname ? filename : pathname);
202 if (action & IMA_APPRAISE)
203 rc = ima_appraise_measurement(iint, file,
204 !pathname ? filename : pathname);
181 kfree(pathbuf); 205 kfree(pathbuf);
182out: 206out:
183 mutex_unlock(&iint->mutex); 207 mutex_unlock(&inode->i_mutex);
184 return rc; 208 return (rc && must_appraise) ? -EACCES : 0;
185} 209}
186 210
187/** 211/**
@@ -197,14 +221,14 @@ out:
197 */ 221 */
198int ima_file_mmap(struct file *file, unsigned long prot) 222int ima_file_mmap(struct file *file, unsigned long prot)
199{ 223{
200 int rc; 224 int rc = 0;
201 225
202 if (!file) 226 if (!file)
203 return 0; 227 return 0;
204 if (prot & PROT_EXEC) 228 if (prot & PROT_EXEC)
205 rc = process_measurement(file, file->f_dentry->d_name.name, 229 rc = process_measurement(file, file->f_dentry->d_name.name,
206 MAY_EXEC, FILE_MMAP); 230 MAY_EXEC, FILE_MMAP);
207 return 0; 231 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
208} 232}
209 233
210/** 234/**
@@ -228,7 +252,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
228 (strcmp(bprm->filename, bprm->interp) == 0) ? 252 (strcmp(bprm->filename, bprm->interp) == 0) ?
229 bprm->filename : bprm->interp, 253 bprm->filename : bprm->interp,
230 MAY_EXEC, BPRM_CHECK); 254 MAY_EXEC, BPRM_CHECK);
231 return 0; 255 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
232} 256}
233 257
234/** 258/**
@@ -249,7 +273,7 @@ int ima_file_check(struct file *file, int mask)
249 rc = process_measurement(file, file->f_dentry->d_name.name, 273 rc = process_measurement(file, file->f_dentry->d_name.name,
250 mask & (MAY_READ | MAY_WRITE | MAY_EXEC), 274 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
251 FILE_CHECK); 275 FILE_CHECK);
252 return 0; 276 return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0;
253} 277}
254EXPORT_SYMBOL_GPL(ima_file_check); 278EXPORT_SYMBOL_GPL(ima_file_check);
255 279
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 1a9583008aae..0d6d60b4ba6f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -24,22 +24,30 @@
24#define IMA_MASK 0x0002 24#define IMA_MASK 0x0002
25#define IMA_FSMAGIC 0x0004 25#define IMA_FSMAGIC 0x0004
26#define IMA_UID 0x0008 26#define IMA_UID 0x0008
27#define IMA_FOWNER 0x0010
27 28
28enum ima_action { UNKNOWN = -1, DONT_MEASURE = 0, MEASURE }; 29#define UNKNOWN 0
30#define MEASURE 1 /* same as IMA_MEASURE */
31#define DONT_MEASURE 2
32#define MEASURE_MASK 3
33#define APPRAISE 4 /* same as IMA_APPRAISE */
34#define DONT_APPRAISE 8
35#define APPRAISE_MASK 12
29 36
30#define MAX_LSM_RULES 6 37#define MAX_LSM_RULES 6
31enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, 38enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
32 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE 39 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
33}; 40};
34 41
35struct ima_measure_rule_entry { 42struct ima_rule_entry {
36 struct list_head list; 43 struct list_head list;
37 enum ima_action action; 44 int action;
38 unsigned int flags; 45 unsigned int flags;
39 enum ima_hooks func; 46 enum ima_hooks func;
40 int mask; 47 int mask;
41 unsigned long fsmagic; 48 unsigned long fsmagic;
42 uid_t uid; 49 uid_t uid;
50 uid_t fowner;
43 struct { 51 struct {
44 void *rule; /* LSM file metadata specific */ 52 void *rule; /* LSM file metadata specific */
45 int type; /* audit type */ 53 int type; /* audit type */
@@ -48,7 +56,7 @@ struct ima_measure_rule_entry {
48 56
49/* 57/*
50 * Without LSM specific knowledge, the default policy can only be 58 * Without LSM specific knowledge, the default policy can only be
51 * written in terms of .action, .func, .mask, .fsmagic, and .uid 59 * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner
52 */ 60 */
53 61
54/* 62/*
@@ -57,7 +65,7 @@ struct ima_measure_rule_entry {
57 * normal users can easily run the machine out of memory simply building 65 * normal users can easily run the machine out of memory simply building
58 * and running executables. 66 * and running executables.
59 */ 67 */
60static struct ima_measure_rule_entry default_rules[] = { 68static struct ima_rule_entry default_rules[] = {
61 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, 69 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
62 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 70 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
63 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 71 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
@@ -75,19 +83,41 @@ static struct ima_measure_rule_entry default_rules[] = {
75 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 83 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
76}; 84};
77 85
78static LIST_HEAD(measure_default_rules); 86static struct ima_rule_entry default_appraise_rules[] = {
79static LIST_HEAD(measure_policy_rules); 87 {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
80static struct list_head *ima_measure; 88 {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
89 {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
90 {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
91 {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
92 {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
93 {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
94 {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
95 {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
96 {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC},
97 {.action = APPRAISE,.fowner = 0,.flags = IMA_FOWNER},
98};
99
100static LIST_HEAD(ima_default_rules);
101static LIST_HEAD(ima_policy_rules);
102static struct list_head *ima_rules;
81 103
82static DEFINE_MUTEX(ima_measure_mutex); 104static DEFINE_MUTEX(ima_rules_mutex);
83 105
84static bool ima_use_tcb __initdata; 106static bool ima_use_tcb __initdata;
85static int __init default_policy_setup(char *str) 107static int __init default_measure_policy_setup(char *str)
86{ 108{
87 ima_use_tcb = 1; 109 ima_use_tcb = 1;
88 return 1; 110 return 1;
89} 111}
90__setup("ima_tcb", default_policy_setup); 112__setup("ima_tcb", default_measure_policy_setup);
113
114static bool ima_use_appraise_tcb __initdata;
115static int __init default_appraise_policy_setup(char *str)
116{
117 ima_use_appraise_tcb = 1;
118 return 1;
119}
120__setup("ima_appraise_tcb", default_appraise_policy_setup);
91 121
92/** 122/**
93 * ima_match_rules - determine whether an inode matches the measure rule. 123 * ima_match_rules - determine whether an inode matches the measure rule.
@@ -98,7 +128,7 @@ __setup("ima_tcb", default_policy_setup);
98 * 128 *
99 * Returns true on rule match, false on failure. 129 * Returns true on rule match, false on failure.
100 */ 130 */
101static bool ima_match_rules(struct ima_measure_rule_entry *rule, 131static bool ima_match_rules(struct ima_rule_entry *rule,
102 struct inode *inode, enum ima_hooks func, int mask) 132 struct inode *inode, enum ima_hooks func, int mask)
103{ 133{
104 struct task_struct *tsk = current; 134 struct task_struct *tsk = current;
@@ -114,6 +144,8 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
114 return false; 144 return false;
115 if ((rule->flags & IMA_UID) && rule->uid != cred->uid) 145 if ((rule->flags & IMA_UID) && rule->uid != cred->uid)
116 return false; 146 return false;
147 if ((rule->flags & IMA_FOWNER) && rule->fowner != inode->i_uid)
148 return false;
117 for (i = 0; i < MAX_LSM_RULES; i++) { 149 for (i = 0; i < MAX_LSM_RULES; i++) {
118 int rc = 0; 150 int rc = 0;
119 u32 osid, sid; 151 u32 osid, sid;
@@ -163,39 +195,58 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
163 * as elements in the list are never deleted, nor does the list 195 * as elements in the list are never deleted, nor does the list
164 * change.) 196 * change.)
165 */ 197 */
166int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask) 198int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
199 int flags)
167{ 200{
168 struct ima_measure_rule_entry *entry; 201 struct ima_rule_entry *entry;
202 int action = 0, actmask = flags | (flags << 1);
169 203
170 list_for_each_entry(entry, ima_measure, list) { 204 list_for_each_entry(entry, ima_rules, list) {
171 bool rc;
172 205
173 rc = ima_match_rules(entry, inode, func, mask); 206 if (!(entry->action & actmask))
174 if (rc) 207 continue;
175 return entry->action; 208
209 if (!ima_match_rules(entry, inode, func, mask))
210 continue;
211
212 action |= (entry->action & (IMA_APPRAISE | IMA_MEASURE));
213 actmask &= (entry->action & APPRAISE_MASK) ?
214 ~APPRAISE_MASK : ~MEASURE_MASK;
215 if (!actmask)
216 break;
176 } 217 }
177 return 0; 218
219 return action;
178} 220}
179 221
180/** 222/**
181 * ima_init_policy - initialize the default measure rules. 223 * ima_init_policy - initialize the default measure rules.
182 * 224 *
183 * ima_measure points to either the measure_default_rules or the 225 * ima_rules points to either the ima_default_rules or the
184 * the new measure_policy_rules. 226 * the new ima_policy_rules.
185 */ 227 */
186void __init ima_init_policy(void) 228void __init ima_init_policy(void)
187{ 229{
188 int i, entries; 230 int i, measure_entries, appraise_entries;
189 231
190 /* if !ima_use_tcb set entries = 0 so we load NO default rules */ 232 /* if !ima_use_tcb set entries = 0 so we load NO default rules */
191 if (ima_use_tcb) 233 measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0;
192 entries = ARRAY_SIZE(default_rules); 234 appraise_entries = ima_use_appraise_tcb ?
193 else 235 ARRAY_SIZE(default_appraise_rules) : 0;
194 entries = 0; 236
195 237 for (i = 0; i < measure_entries + appraise_entries; i++) {
196 for (i = 0; i < entries; i++) 238 if (i < measure_entries)
197 list_add_tail(&default_rules[i].list, &measure_default_rules); 239 list_add_tail(&default_rules[i].list,
198 ima_measure = &measure_default_rules; 240 &ima_default_rules);
241 else {
242 int j = i - measure_entries;
243
244 list_add_tail(&default_appraise_rules[j].list,
245 &ima_default_rules);
246 }
247 }
248
249 ima_rules = &ima_default_rules;
199} 250}
200 251
201/** 252/**
@@ -212,8 +263,8 @@ void ima_update_policy(void)
212 int result = 1; 263 int result = 1;
213 int audit_info = 0; 264 int audit_info = 0;
214 265
215 if (ima_measure == &measure_default_rules) { 266 if (ima_rules == &ima_default_rules) {
216 ima_measure = &measure_policy_rules; 267 ima_rules = &ima_policy_rules;
217 cause = "complete"; 268 cause = "complete";
218 result = 0; 269 result = 0;
219 } 270 }
@@ -224,14 +275,17 @@ void ima_update_policy(void)
224enum { 275enum {
225 Opt_err = -1, 276 Opt_err = -1,
226 Opt_measure = 1, Opt_dont_measure, 277 Opt_measure = 1, Opt_dont_measure,
278 Opt_appraise, Opt_dont_appraise,
227 Opt_obj_user, Opt_obj_role, Opt_obj_type, 279 Opt_obj_user, Opt_obj_role, Opt_obj_type,
228 Opt_subj_user, Opt_subj_role, Opt_subj_type, 280 Opt_subj_user, Opt_subj_role, Opt_subj_type,
229 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid 281 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner
230}; 282};
231 283
232static match_table_t policy_tokens = { 284static match_table_t policy_tokens = {
233 {Opt_measure, "measure"}, 285 {Opt_measure, "measure"},
234 {Opt_dont_measure, "dont_measure"}, 286 {Opt_dont_measure, "dont_measure"},
287 {Opt_appraise, "appraise"},
288 {Opt_dont_appraise, "dont_appraise"},
235 {Opt_obj_user, "obj_user=%s"}, 289 {Opt_obj_user, "obj_user=%s"},
236 {Opt_obj_role, "obj_role=%s"}, 290 {Opt_obj_role, "obj_role=%s"},
237 {Opt_obj_type, "obj_type=%s"}, 291 {Opt_obj_type, "obj_type=%s"},
@@ -242,10 +296,11 @@ static match_table_t policy_tokens = {
242 {Opt_mask, "mask=%s"}, 296 {Opt_mask, "mask=%s"},
243 {Opt_fsmagic, "fsmagic=%s"}, 297 {Opt_fsmagic, "fsmagic=%s"},
244 {Opt_uid, "uid=%s"}, 298 {Opt_uid, "uid=%s"},
299 {Opt_fowner, "fowner=%s"},
245 {Opt_err, NULL} 300 {Opt_err, NULL}
246}; 301};
247 302
248static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, 303static int ima_lsm_rule_init(struct ima_rule_entry *entry,
249 char *args, int lsm_rule, int audit_type) 304 char *args, int lsm_rule, int audit_type)
250{ 305{
251 int result; 306 int result;
@@ -269,7 +324,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
269 audit_log_format(ab, " "); 324 audit_log_format(ab, " ");
270} 325}
271 326
272static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) 327static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
273{ 328{
274 struct audit_buffer *ab; 329 struct audit_buffer *ab;
275 char *p; 330 char *p;
@@ -278,6 +333,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
278 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); 333 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
279 334
280 entry->uid = -1; 335 entry->uid = -1;
336 entry->fowner = -1;
281 entry->action = UNKNOWN; 337 entry->action = UNKNOWN;
282 while ((p = strsep(&rule, " \t")) != NULL) { 338 while ((p = strsep(&rule, " \t")) != NULL) {
283 substring_t args[MAX_OPT_ARGS]; 339 substring_t args[MAX_OPT_ARGS];
@@ -306,11 +362,27 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
306 362
307 entry->action = DONT_MEASURE; 363 entry->action = DONT_MEASURE;
308 break; 364 break;
365 case Opt_appraise:
366 ima_log_string(ab, "action", "appraise");
367
368 if (entry->action != UNKNOWN)
369 result = -EINVAL;
370
371 entry->action = APPRAISE;
372 break;
373 case Opt_dont_appraise:
374 ima_log_string(ab, "action", "dont_appraise");
375
376 if (entry->action != UNKNOWN)
377 result = -EINVAL;
378
379 entry->action = DONT_APPRAISE;
380 break;
309 case Opt_func: 381 case Opt_func:
310 ima_log_string(ab, "func", args[0].from); 382 ima_log_string(ab, "func", args[0].from);
311 383
312 if (entry->func) 384 if (entry->func)
313 result = -EINVAL; 385 result = -EINVAL;
314 386
315 if (strcmp(args[0].from, "FILE_CHECK") == 0) 387 if (strcmp(args[0].from, "FILE_CHECK") == 0)
316 entry->func = FILE_CHECK; 388 entry->func = FILE_CHECK;
@@ -375,6 +447,23 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
375 entry->flags |= IMA_UID; 447 entry->flags |= IMA_UID;
376 } 448 }
377 break; 449 break;
450 case Opt_fowner:
451 ima_log_string(ab, "fowner", args[0].from);
452
453 if (entry->fowner != -1) {
454 result = -EINVAL;
455 break;
456 }
457
458 result = strict_strtoul(args[0].from, 10, &lnum);
459 if (!result) {
460 entry->fowner = (uid_t) lnum;
461 if (entry->fowner != lnum)
462 result = -EINVAL;
463 else
464 entry->flags |= IMA_FOWNER;
465 }
466 break;
378 case Opt_obj_user: 467 case Opt_obj_user:
379 ima_log_string(ab, "obj_user", args[0].from); 468 ima_log_string(ab, "obj_user", args[0].from);
380 result = ima_lsm_rule_init(entry, args[0].from, 469 result = ima_lsm_rule_init(entry, args[0].from,
@@ -426,7 +515,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
426} 515}
427 516
428/** 517/**
429 * ima_parse_add_rule - add a rule to measure_policy_rules 518 * ima_parse_add_rule - add a rule to ima_policy_rules
430 * @rule - ima measurement policy rule 519 * @rule - ima measurement policy rule
431 * 520 *
432 * Uses a mutex to protect the policy list from multiple concurrent writers. 521 * Uses a mutex to protect the policy list from multiple concurrent writers.
@@ -436,12 +525,12 @@ ssize_t ima_parse_add_rule(char *rule)
436{ 525{
437 const char *op = "update_policy"; 526 const char *op = "update_policy";
438 char *p; 527 char *p;
439 struct ima_measure_rule_entry *entry; 528 struct ima_rule_entry *entry;
440 ssize_t result, len; 529 ssize_t result, len;
441 int audit_info = 0; 530 int audit_info = 0;
442 531
443 /* Prevent installed policy from changing */ 532 /* Prevent installed policy from changing */
444 if (ima_measure != &measure_default_rules) { 533 if (ima_rules != &ima_default_rules) {
445 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 534 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
446 NULL, op, "already exists", 535 NULL, op, "already exists",
447 -EACCES, audit_info); 536 -EACCES, audit_info);
@@ -474,9 +563,9 @@ ssize_t ima_parse_add_rule(char *rule)
474 return result; 563 return result;
475 } 564 }
476 565
477 mutex_lock(&ima_measure_mutex); 566 mutex_lock(&ima_rules_mutex);
478 list_add_tail(&entry->list, &measure_policy_rules); 567 list_add_tail(&entry->list, &ima_policy_rules);
479 mutex_unlock(&ima_measure_mutex); 568 mutex_unlock(&ima_rules_mutex);
480 569
481 return len; 570 return len;
482} 571}
@@ -484,12 +573,12 @@ ssize_t ima_parse_add_rule(char *rule)
484/* ima_delete_rules called to cleanup invalid policy */ 573/* ima_delete_rules called to cleanup invalid policy */
485void ima_delete_rules(void) 574void ima_delete_rules(void)
486{ 575{
487 struct ima_measure_rule_entry *entry, *tmp; 576 struct ima_rule_entry *entry, *tmp;
488 577
489 mutex_lock(&ima_measure_mutex); 578 mutex_lock(&ima_rules_mutex);
490 list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) { 579 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
491 list_del(&entry->list); 580 list_del(&entry->list);
492 kfree(entry); 581 kfree(entry);
493 } 582 }
494 mutex_unlock(&ima_measure_mutex); 583 mutex_unlock(&ima_rules_mutex);
495} 584}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7a25ecec5aaa..4eec1b14193e 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -16,7 +16,12 @@
16#include <crypto/sha.h> 16#include <crypto/sha.h>
17 17
18/* iint cache flags */ 18/* iint cache flags */
19#define IMA_MEASURED 0x01 19#define IMA_MEASURE 0x01
20#define IMA_MEASURED 0x02
21#define IMA_APPRAISE 0x04
22#define IMA_APPRAISED 0x08
23#define IMA_COLLECTED 0x10
24#define IMA_DIGSIG 0x20
20 25
21enum evm_ima_xattr_type { 26enum evm_ima_xattr_type {
22 IMA_XATTR_DIGEST = 0x01, 27 IMA_XATTR_DIGEST = 0x01,
@@ -35,8 +40,8 @@ struct integrity_iint_cache {
35 struct inode *inode; /* back pointer to inode in question */ 40 struct inode *inode; /* back pointer to inode in question */
36 u64 version; /* track inode changes */ 41 u64 version; /* track inode changes */
37 unsigned char flags; 42 unsigned char flags;
38 u8 digest[SHA1_DIGEST_SIZE]; 43 struct evm_ima_xattr_data ima_xattr;
39 struct mutex mutex; /* protects: version, flags, digest */ 44 enum integrity_status ima_status;
40 enum integrity_status evm_status; 45 enum integrity_status evm_status;
41}; 46};
42 47
diff --git a/security/security.c b/security/security.c
index 68c1b9b45d93..d23b43522a5a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -573,6 +573,9 @@ int security_inode_setxattr(struct dentry *dentry, const char *name,
573 ret = security_ops->inode_setxattr(dentry, name, value, size, flags); 573 ret = security_ops->inode_setxattr(dentry, name, value, size, flags);
574 if (ret) 574 if (ret)
575 return ret; 575 return ret;
576 ret = ima_inode_setxattr(dentry, name, value, size);
577 if (ret)
578 return ret;
576 return evm_inode_setxattr(dentry, name, value, size); 579 return evm_inode_setxattr(dentry, name, value, size);
577} 580}
578 581
@@ -608,6 +611,9 @@ int security_inode_removexattr(struct dentry *dentry, const char *name)
608 ret = security_ops->inode_removexattr(dentry, name); 611 ret = security_ops->inode_removexattr(dentry, name);
609 if (ret) 612 if (ret)
610 return ret; 613 return ret;
614 ret = ima_inode_removexattr(dentry, name);
615 if (ret)
616 return ret;
611 return evm_inode_removexattr(dentry, name); 617 return evm_inode_removexattr(dentry, name);
612} 618}
613 619