aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_appraise.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/ima/ima_appraise.c')
-rw-r--r--security/integrity/ima/ima_appraise.c92
1 files changed, 73 insertions, 19 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index bdc8ba1d1d27..2d4becab8918 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -42,12 +42,69 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE); 42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
43} 43}
44 44
45static void ima_fix_xattr(struct dentry *dentry, 45static int ima_fix_xattr(struct dentry *dentry,
46 struct integrity_iint_cache *iint) 46 struct integrity_iint_cache *iint)
47{ 47{
48 iint->ima_xattr.type = IMA_XATTR_DIGEST; 48 iint->ima_xattr.type = IMA_XATTR_DIGEST;
49 __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA, (u8 *)&iint->ima_xattr, 49 return __vfs_setxattr_noperm(dentry, XATTR_NAME_IMA,
50 sizeof iint->ima_xattr, 0); 50 (u8 *)&iint->ima_xattr,
51 sizeof(iint->ima_xattr), 0);
52}
53
54/* Return specific func appraised cached result */
55enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
56 int func)
57{
58 switch(func) {
59 case MMAP_CHECK:
60 return iint->ima_mmap_status;
61 case BPRM_CHECK:
62 return iint->ima_bprm_status;
63 case MODULE_CHECK:
64 return iint->ima_module_status;
65 case FILE_CHECK:
66 default:
67 return iint->ima_file_status;
68 }
69}
70
71static void ima_set_cache_status(struct integrity_iint_cache *iint,
72 int func, enum integrity_status status)
73{
74 switch(func) {
75 case MMAP_CHECK:
76 iint->ima_mmap_status = status;
77 break;
78 case BPRM_CHECK:
79 iint->ima_bprm_status = status;
80 break;
81 case MODULE_CHECK:
82 iint->ima_module_status = status;
83 break;
84 case FILE_CHECK:
85 default:
86 iint->ima_file_status = status;
87 break;
88 }
89}
90
91static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
92{
93 switch(func) {
94 case MMAP_CHECK:
95 iint->flags |= (IMA_MMAP_APPRAISED | IMA_APPRAISED);
96 break;
97 case BPRM_CHECK:
98 iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
99 break;
100 case MODULE_CHECK:
101 iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
102 break;
103 case FILE_CHECK:
104 default:
105 iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
106 break;
107 }
51} 108}
52 109
53/* 110/*
@@ -58,7 +115,7 @@ static void ima_fix_xattr(struct dentry *dentry,
58 * 115 *
59 * Return 0 on success, error code otherwise 116 * Return 0 on success, error code otherwise
60 */ 117 */
61int ima_appraise_measurement(struct integrity_iint_cache *iint, 118int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
62 struct file *file, const unsigned char *filename) 119 struct file *file, const unsigned char *filename)
63{ 120{
64 struct dentry *dentry = file->f_dentry; 121 struct dentry *dentry = file->f_dentry;
@@ -74,9 +131,6 @@ int ima_appraise_measurement(struct integrity_iint_cache *iint,
74 if (!inode->i_op->getxattr) 131 if (!inode->i_op->getxattr)
75 return INTEGRITY_UNKNOWN; 132 return INTEGRITY_UNKNOWN;
76 133
77 if (iint->flags & IMA_APPRAISED)
78 return iint->ima_status;
79
80 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value, 134 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_IMA, (char **)&xattr_value,
81 0, GFP_NOFS); 135 0, GFP_NOFS);
82 if (rc <= 0) { 136 if (rc <= 0) {
@@ -98,19 +152,18 @@ int ima_appraise_measurement(struct integrity_iint_cache *iint,
98 cause = "invalid-HMAC"; 152 cause = "invalid-HMAC";
99 goto out; 153 goto out;
100 } 154 }
101
102 switch (xattr_value->type) { 155 switch (xattr_value->type) {
103 case IMA_XATTR_DIGEST: 156 case IMA_XATTR_DIGEST:
157 if (iint->flags & IMA_DIGSIG_REQUIRED) {
158 cause = "IMA signature required";
159 status = INTEGRITY_FAIL;
160 break;
161 }
104 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest, 162 rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
105 IMA_DIGEST_SIZE); 163 IMA_DIGEST_SIZE);
106 if (rc) { 164 if (rc) {
107 cause = "invalid-hash"; 165 cause = "invalid-hash";
108 status = INTEGRITY_FAIL; 166 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; 167 break;
115 } 168 }
116 status = INTEGRITY_PASS; 169 status = INTEGRITY_PASS;
@@ -141,15 +194,15 @@ out:
141 if ((ima_appraise & IMA_APPRAISE_FIX) && 194 if ((ima_appraise & IMA_APPRAISE_FIX) &&
142 (!xattr_value || 195 (!xattr_value ||
143 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { 196 xattr_value->type != EVM_IMA_XATTR_DIGSIG)) {
144 ima_fix_xattr(dentry, iint); 197 if (!ima_fix_xattr(dentry, iint))
145 status = INTEGRITY_PASS; 198 status = INTEGRITY_PASS;
146 } 199 }
147 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, 200 integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename,
148 op, cause, rc, 0); 201 op, cause, rc, 0);
149 } else { 202 } else {
150 iint->flags |= IMA_APPRAISED; 203 ima_cache_flags(iint, func);
151 } 204 }
152 iint->ima_status = status; 205 ima_set_cache_status(iint, func, status);
153 kfree(xattr_value); 206 kfree(xattr_value);
154 return status; 207 return status;
155} 208}
@@ -195,10 +248,11 @@ void ima_inode_post_setattr(struct dentry *dentry)
195 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR); 248 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
196 iint = integrity_iint_find(inode); 249 iint = integrity_iint_find(inode);
197 if (iint) { 250 if (iint) {
251 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
252 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
253 IMA_ACTION_FLAGS);
198 if (must_appraise) 254 if (must_appraise)
199 iint->flags |= IMA_APPRAISE; 255 iint->flags |= IMA_APPRAISE;
200 else
201 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED);
202 } 256 }
203 if (!must_appraise) 257 if (!must_appraise)
204 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); 258 rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA);