summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 16:07:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-31 16:07:35 -0500
commit3c29548f87f9545f2f3c1cd1a784fae8ad2d53ba (patch)
treea6ee072fea6f32e40fad48319ddf3cc3eca53dcb /security/integrity/ima
parente1c70f32386c4984ed8ca1a7aedb9bbff9ed3414 (diff)
parent36447456e1cca853188505f2a964dbbeacfc7a7a (diff)
Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull integrity updates from James Morris: "This contains a mixture of bug fixes, code cleanup, and new functionality. Of note is the integrity cache locking fix, file change detection, and support for a new EVM portable and immutable signature type. The re-introduction of the integrity cache lock (iint) fixes the problem of attempting to take the i_rwsem shared a second time, when it was previously taken exclusively. Defining atomic flags resolves the original iint/i_rwsem circular locking - accessing the file data vs. modifying the file metadata. Although it fixes the O_DIRECT problem as well, a subsequent patch is needed to remove the explicit O_DIRECT prevention. For performance reasons, detecting when a file has changed and needs to be re-measured, re-appraised, and/or re-audited, was limited to after the last writer has closed, and only if the file data has changed. Detecting file change is based on i_version. For filesystems that do not support i_version, remote filesystems, or userspace filesystems, the file was measured, appraised and/or audited once and never re-evaluated. Now local filesystems, which do not support i_version or are not mounted with the i_version option, assume the file has changed and are required to re-evaluate the file. This change does not address detecting file change on remote or userspace filesystems. Unlike file data signatures, which can be included and distributed in software packages (eg. rpm, deb), the existing EVM signature, which protects the file metadata, could not be included in software packages, as it includes file system specific information (eg. i_ino, possibly the UUID). This pull request defines a new EVM portable and immutable file metadata signature format, which can be included in software packages" * 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: ima/policy: fix parsing of fsuuid ima: Use i_version only when filesystem supports it integrity: remove unneeded initializations in integrity_iint_cache entries ima: log message to module appraisal error ima: pass filename to ima_rdwr_violation_check() ima: Fix line continuation format ima: support new "hash" and "dont_hash" policy actions ima: re-introduce own integrity cache lock EVM: Add support for portable signature format EVM: Allow userland to permit modification of EVM-protected metadata ima: relax requiring a file signature for new files with zero length
Diffstat (limited to 'security/integrity/ima')
-rw-r--r--security/integrity/ima/ima_api.c2
-rw-r--r--security/integrity/ima/ima_appraise.c46
-rw-r--r--security/integrity/ima/ima_main.c92
-rw-r--r--security/integrity/ima/ima_policy.c32
-rw-r--r--security/integrity/ima/ima_template.c11
5 files changed, 127 insertions, 56 deletions
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index c6ae42266270..08fe405338e1 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -175,7 +175,7 @@ err_out:
175 */ 175 */
176int ima_get_action(struct inode *inode, int mask, enum ima_hooks func, int *pcr) 176int ima_get_action(struct inode *inode, int mask, enum ima_hooks func, int *pcr)
177{ 177{
178 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; 178 int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
179 179
180 flags &= ima_policy_flag; 180 flags &= ima_policy_flag;
181 181
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 65fbcf3c32c7..f2803a40ff82 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -46,14 +46,15 @@ bool is_ima_appraise_enabled(void)
46/* 46/*
47 * ima_must_appraise - set appraise flag 47 * ima_must_appraise - set appraise flag
48 * 48 *
49 * Return 1 to appraise 49 * Return 1 to appraise or hash
50 */ 50 */
51int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) 51int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
52{ 52{
53 if (!ima_appraise) 53 if (!ima_appraise)
54 return 0; 54 return 0;
55 55
56 return ima_match_policy(inode, func, mask, IMA_APPRAISE, NULL); 56 return ima_match_policy(inode, func, mask, IMA_APPRAISE | IMA_HASH,
57 NULL);
57} 58}
58 59
59static int ima_fix_xattr(struct dentry *dentry, 60static int ima_fix_xattr(struct dentry *dentry,
@@ -223,13 +224,16 @@ int ima_appraise_measurement(enum ima_hooks func,
223 if (opened & FILE_CREATED) 224 if (opened & FILE_CREATED)
224 iint->flags |= IMA_NEW_FILE; 225 iint->flags |= IMA_NEW_FILE;
225 if ((iint->flags & IMA_NEW_FILE) && 226 if ((iint->flags & IMA_NEW_FILE) &&
226 !(iint->flags & IMA_DIGSIG_REQUIRED)) 227 (!(iint->flags & IMA_DIGSIG_REQUIRED) ||
228 (inode->i_size == 0)))
227 status = INTEGRITY_PASS; 229 status = INTEGRITY_PASS;
228 goto out; 230 goto out;
229 } 231 }
230 232
231 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint); 233 status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint);
232 if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) { 234 if ((status != INTEGRITY_PASS) &&
235 (status != INTEGRITY_PASS_IMMUTABLE) &&
236 (status != INTEGRITY_UNKNOWN)) {
233 if ((status == INTEGRITY_NOLABEL) 237 if ((status == INTEGRITY_NOLABEL)
234 || (status == INTEGRITY_NOXATTRS)) 238 || (status == INTEGRITY_NOXATTRS))
235 cause = "missing-HMAC"; 239 cause = "missing-HMAC";
@@ -248,6 +252,7 @@ int ima_appraise_measurement(enum ima_hooks func,
248 status = INTEGRITY_FAIL; 252 status = INTEGRITY_FAIL;
249 break; 253 break;
250 } 254 }
255 clear_bit(IMA_DIGSIG, &iint->atomic_flags);
251 if (xattr_len - sizeof(xattr_value->type) - hash_start >= 256 if (xattr_len - sizeof(xattr_value->type) - hash_start >=
252 iint->ima_hash->length) 257 iint->ima_hash->length)
253 /* xattr length may be longer. md5 hash in previous 258 /* xattr length may be longer. md5 hash in previous
@@ -266,7 +271,7 @@ int ima_appraise_measurement(enum ima_hooks func,
266 status = INTEGRITY_PASS; 271 status = INTEGRITY_PASS;
267 break; 272 break;
268 case EVM_IMA_XATTR_DIGSIG: 273 case EVM_IMA_XATTR_DIGSIG:
269 iint->flags |= IMA_DIGSIG; 274 set_bit(IMA_DIGSIG, &iint->atomic_flags);
270 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, 275 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
271 (const char *)xattr_value, rc, 276 (const char *)xattr_value, rc,
272 iint->ima_hash->digest, 277 iint->ima_hash->digest,
@@ -317,17 +322,20 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
317 int rc = 0; 322 int rc = 0;
318 323
319 /* do not collect and update hash for digital signatures */ 324 /* do not collect and update hash for digital signatures */
320 if (iint->flags & IMA_DIGSIG) 325 if (test_bit(IMA_DIGSIG, &iint->atomic_flags))
321 return; 326 return;
322 327
323 if (iint->ima_file_status != INTEGRITY_PASS) 328 if ((iint->ima_file_status != INTEGRITY_PASS) &&
329 !(iint->flags & IMA_HASH))
324 return; 330 return;
325 331
326 rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo); 332 rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo);
327 if (rc < 0) 333 if (rc < 0)
328 return; 334 return;
329 335
336 inode_lock(file_inode(file));
330 ima_fix_xattr(dentry, iint); 337 ima_fix_xattr(dentry, iint);
338 inode_unlock(file_inode(file));
331} 339}
332 340
333/** 341/**
@@ -343,23 +351,21 @@ void ima_inode_post_setattr(struct dentry *dentry)
343{ 351{
344 struct inode *inode = d_backing_inode(dentry); 352 struct inode *inode = d_backing_inode(dentry);
345 struct integrity_iint_cache *iint; 353 struct integrity_iint_cache *iint;
346 int must_appraise; 354 int action;
347 355
348 if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode) 356 if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)
349 || !(inode->i_opflags & IOP_XATTR)) 357 || !(inode->i_opflags & IOP_XATTR))
350 return; 358 return;
351 359
352 must_appraise = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR); 360 action = ima_must_appraise(inode, MAY_ACCESS, POST_SETATTR);
361 if (!action)
362 __vfs_removexattr(dentry, XATTR_NAME_IMA);
353 iint = integrity_iint_find(inode); 363 iint = integrity_iint_find(inode);
354 if (iint) { 364 if (iint) {
355 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED | 365 set_bit(IMA_CHANGE_ATTR, &iint->atomic_flags);
356 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK | 366 if (!action)
357 IMA_ACTION_RULE_FLAGS); 367 clear_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
358 if (must_appraise)
359 iint->flags |= IMA_APPRAISE;
360 } 368 }
361 if (!must_appraise)
362 __vfs_removexattr(dentry, XATTR_NAME_IMA);
363} 369}
364 370
365/* 371/*
@@ -388,12 +394,12 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
388 iint = integrity_iint_find(inode); 394 iint = integrity_iint_find(inode);
389 if (!iint) 395 if (!iint)
390 return; 396 return;
391
392 iint->flags &= ~IMA_DONE_MASK;
393 iint->measured_pcrs = 0; 397 iint->measured_pcrs = 0;
398 set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
394 if (digsig) 399 if (digsig)
395 iint->flags |= IMA_DIGSIG; 400 set_bit(IMA_DIGSIG, &iint->atomic_flags);
396 return; 401 else
402 clear_bit(IMA_DIGSIG, &iint->atomic_flags);
397} 403}
398 404
399int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, 405int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 06a70c5a2329..061425dd6400 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -85,10 +85,10 @@ static void ima_rdwr_violation_check(struct file *file,
85 struct integrity_iint_cache *iint, 85 struct integrity_iint_cache *iint,
86 int must_measure, 86 int must_measure,
87 char **pathbuf, 87 char **pathbuf,
88 const char **pathname) 88 const char **pathname,
89 char *filename)
89{ 90{
90 struct inode *inode = file_inode(file); 91 struct inode *inode = file_inode(file);
91 char filename[NAME_MAX];
92 fmode_t mode = file->f_mode; 92 fmode_t mode = file->f_mode;
93 bool send_tomtou = false, send_writers = false; 93 bool send_tomtou = false, send_writers = false;
94 94
@@ -97,10 +97,13 @@ static void ima_rdwr_violation_check(struct file *file,
97 if (!iint) 97 if (!iint)
98 iint = integrity_iint_find(inode); 98 iint = integrity_iint_find(inode);
99 /* IMA_MEASURE is set from reader side */ 99 /* IMA_MEASURE is set from reader side */
100 if (iint && (iint->flags & IMA_MEASURE)) 100 if (iint && test_bit(IMA_MUST_MEASURE,
101 &iint->atomic_flags))
101 send_tomtou = true; 102 send_tomtou = true;
102 } 103 }
103 } else { 104 } else {
105 if (must_measure)
106 set_bit(IMA_MUST_MEASURE, &iint->atomic_flags);
104 if ((atomic_read(&inode->i_writecount) > 0) && must_measure) 107 if ((atomic_read(&inode->i_writecount) > 0) && must_measure)
105 send_writers = true; 108 send_writers = true;
106 } 109 }
@@ -122,22 +125,25 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
122 struct inode *inode, struct file *file) 125 struct inode *inode, struct file *file)
123{ 126{
124 fmode_t mode = file->f_mode; 127 fmode_t mode = file->f_mode;
128 bool update;
125 129
126 if (!(mode & FMODE_WRITE)) 130 if (!(mode & FMODE_WRITE))
127 return; 131 return;
128 132
129 inode_lock(inode); 133 mutex_lock(&iint->mutex);
130 if (atomic_read(&inode->i_writecount) == 1) { 134 if (atomic_read(&inode->i_writecount) == 1) {
135 update = test_and_clear_bit(IMA_UPDATE_XATTR,
136 &iint->atomic_flags);
131 if (!IS_I_VERSION(inode) || 137 if (!IS_I_VERSION(inode) ||
132 inode_cmp_iversion(inode, iint->version) || 138 inode_cmp_iversion(inode, iint->version) ||
133 (iint->flags & IMA_NEW_FILE)) { 139 (iint->flags & IMA_NEW_FILE)) {
134 iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE); 140 iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
135 iint->measured_pcrs = 0; 141 iint->measured_pcrs = 0;
136 if (iint->flags & IMA_APPRAISE) 142 if (update)
137 ima_update_xattr(iint, file); 143 ima_update_xattr(iint, file);
138 } 144 }
139 } 145 }
140 inode_unlock(inode); 146 mutex_unlock(&iint->mutex);
141} 147}
142 148
143/** 149/**
@@ -170,7 +176,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
170 char *pathbuf = NULL; 176 char *pathbuf = NULL;
171 char filename[NAME_MAX]; 177 char filename[NAME_MAX];
172 const char *pathname = NULL; 178 const char *pathname = NULL;
173 int rc = -ENOMEM, action, must_appraise; 179 int rc = 0, action, must_appraise = 0;
174 int pcr = CONFIG_IMA_MEASURE_PCR_IDX; 180 int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
175 struct evm_ima_xattr_data *xattr_value = NULL; 181 struct evm_ima_xattr_data *xattr_value = NULL;
176 int xattr_len = 0; 182 int xattr_len = 0;
@@ -201,17 +207,31 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
201 if (action) { 207 if (action) {
202 iint = integrity_inode_get(inode); 208 iint = integrity_inode_get(inode);
203 if (!iint) 209 if (!iint)
204 goto out; 210 rc = -ENOMEM;
205 } 211 }
206 212
207 if (violation_check) { 213 if (!rc && violation_check)
208 ima_rdwr_violation_check(file, iint, action & IMA_MEASURE, 214 ima_rdwr_violation_check(file, iint, action & IMA_MEASURE,
209 &pathbuf, &pathname); 215 &pathbuf, &pathname, filename);
210 if (!action) { 216
211 rc = 0; 217 inode_unlock(inode);
212 goto out_free; 218
213 } 219 if (rc)
214 } 220 goto out;
221 if (!action)
222 goto out;
223
224 mutex_lock(&iint->mutex);
225
226 if (test_and_clear_bit(IMA_CHANGE_ATTR, &iint->atomic_flags))
227 /* reset appraisal flags if ima_inode_post_setattr was called */
228 iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
229 IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
230 IMA_ACTION_FLAGS);
231
232 if (test_and_clear_bit(IMA_CHANGE_XATTR, &iint->atomic_flags))
233 /* reset all flags if ima_inode_setxattr was called */
234 iint->flags &= ~IMA_DONE_MASK;
215 235
216 /* Determine if already appraised/measured based on bitmask 236 /* Determine if already appraised/measured based on bitmask
217 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED, 237 * (IMA_MEASURE, IMA_MEASURED, IMA_XXXX_APPRAISE, IMA_XXXX_APPRAISED,
@@ -225,11 +245,23 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
225 if ((action & IMA_MEASURE) && (iint->measured_pcrs & (0x1 << pcr))) 245 if ((action & IMA_MEASURE) && (iint->measured_pcrs & (0x1 << pcr)))
226 action ^= IMA_MEASURE; 246 action ^= IMA_MEASURE;
227 247
248 /* HASH sets the digital signature and update flags, nothing else */
249 if ((action & IMA_HASH) &&
250 !(test_bit(IMA_DIGSIG, &iint->atomic_flags))) {
251 xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);
252 if ((xattr_value && xattr_len > 2) &&
253 (xattr_value->type == EVM_IMA_XATTR_DIGSIG))
254 set_bit(IMA_DIGSIG, &iint->atomic_flags);
255 iint->flags |= IMA_HASHED;
256 action ^= IMA_HASH;
257 set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
258 }
259
228 /* Nothing to do, just return existing appraised status */ 260 /* Nothing to do, just return existing appraised status */
229 if (!action) { 261 if (!action) {
230 if (must_appraise) 262 if (must_appraise)
231 rc = ima_get_cache_status(iint, func); 263 rc = ima_get_cache_status(iint, func);
232 goto out_digsig; 264 goto out_locked;
233 } 265 }
234 266
235 template_desc = ima_template_desc_current(); 267 template_desc = ima_template_desc_current();
@@ -242,7 +274,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
242 274
243 rc = ima_collect_measurement(iint, file, buf, size, hash_algo); 275 rc = ima_collect_measurement(iint, file, buf, size, hash_algo);
244 if (rc != 0 && rc != -EBADF && rc != -EINVAL) 276 if (rc != 0 && rc != -EBADF && rc != -EINVAL)
245 goto out_digsig; 277 goto out_locked;
246 278
247 if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */ 279 if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */
248 pathname = ima_d_path(&file->f_path, &pathbuf, filename); 280 pathname = ima_d_path(&file->f_path, &pathbuf, filename);
@@ -250,26 +282,32 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
250 if (action & IMA_MEASURE) 282 if (action & IMA_MEASURE)
251 ima_store_measurement(iint, file, pathname, 283 ima_store_measurement(iint, file, pathname,
252 xattr_value, xattr_len, pcr); 284 xattr_value, xattr_len, pcr);
253 if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) 285 if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
286 inode_lock(inode);
254 rc = ima_appraise_measurement(func, iint, file, pathname, 287 rc = ima_appraise_measurement(func, iint, file, pathname,
255 xattr_value, xattr_len, opened); 288 xattr_value, xattr_len, opened);
289 inode_unlock(inode);
290 }
256 if (action & IMA_AUDIT) 291 if (action & IMA_AUDIT)
257 ima_audit_measurement(iint, pathname); 292 ima_audit_measurement(iint, pathname);
258 293
259 if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO)) 294 if ((file->f_flags & O_DIRECT) && (iint->flags & IMA_PERMIT_DIRECTIO))
260 rc = 0; 295 rc = 0;
261out_digsig: 296out_locked:
262 if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && 297 if ((mask & MAY_WRITE) && test_bit(IMA_DIGSIG, &iint->atomic_flags) &&
263 !(iint->flags & IMA_NEW_FILE)) 298 !(iint->flags & IMA_NEW_FILE))
264 rc = -EACCES; 299 rc = -EACCES;
300 mutex_unlock(&iint->mutex);
265 kfree(xattr_value); 301 kfree(xattr_value);
266out_free: 302out:
267 if (pathbuf) 303 if (pathbuf)
268 __putname(pathbuf); 304 __putname(pathbuf);
269out: 305 if (must_appraise) {
270 inode_unlock(inode); 306 if (rc && (ima_appraise & IMA_APPRAISE_ENFORCE))
271 if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) 307 return -EACCES;
272 return -EACCES; 308 if (file->f_mode & FMODE_WRITE)
309 set_bit(IMA_UPDATE_XATTR, &iint->atomic_flags);
310 }
273 return 0; 311 return 0;
274} 312}
275 313
@@ -368,8 +406,10 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
368 406
369 if (!file && read_id == READING_MODULE) { 407 if (!file && read_id == READING_MODULE) {
370 if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES) && 408 if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES) &&
371 (ima_appraise & IMA_APPRAISE_ENFORCE)) 409 (ima_appraise & IMA_APPRAISE_ENFORCE)) {
410 pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n");
372 return -EACCES; /* INTEGRITY_UNKNOWN */ 411 return -EACCES; /* INTEGRITY_UNKNOWN */
412 }
373 return 0; /* We rely on module signature checking */ 413 return 0; /* We rely on module signature checking */
374 } 414 }
375 return 0; 415 return 0;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index ee4613fa5840..915f5572c6ff 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -40,6 +40,8 @@
40#define APPRAISE 0x0004 /* same as IMA_APPRAISE */ 40#define APPRAISE 0x0004 /* same as IMA_APPRAISE */
41#define DONT_APPRAISE 0x0008 41#define DONT_APPRAISE 0x0008
42#define AUDIT 0x0040 42#define AUDIT 0x0040
43#define HASH 0x0100
44#define DONT_HASH 0x0200
43 45
44#define INVALID_PCR(a) (((a) < 0) || \ 46#define INVALID_PCR(a) (((a) < 0) || \
45 (a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8)) 47 (a) >= (FIELD_SIZEOF(struct integrity_iint_cache, measured_pcrs) * 8))
@@ -380,8 +382,10 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
380 action |= entry->flags & IMA_ACTION_FLAGS; 382 action |= entry->flags & IMA_ACTION_FLAGS;
381 383
382 action |= entry->action & IMA_DO_MASK; 384 action |= entry->action & IMA_DO_MASK;
383 if (entry->action & IMA_APPRAISE) 385 if (entry->action & IMA_APPRAISE) {
384 action |= get_subaction(entry, func); 386 action |= get_subaction(entry, func);
387 action ^= IMA_HASH;
388 }
385 389
386 if (entry->action & IMA_DO_MASK) 390 if (entry->action & IMA_DO_MASK)
387 actmask &= ~(entry->action | entry->action << 1); 391 actmask &= ~(entry->action | entry->action << 1);
@@ -521,7 +525,7 @@ enum {
521 Opt_err = -1, 525 Opt_err = -1,
522 Opt_measure = 1, Opt_dont_measure, 526 Opt_measure = 1, Opt_dont_measure,
523 Opt_appraise, Opt_dont_appraise, 527 Opt_appraise, Opt_dont_appraise,
524 Opt_audit, 528 Opt_audit, Opt_hash, Opt_dont_hash,
525 Opt_obj_user, Opt_obj_role, Opt_obj_type, 529 Opt_obj_user, Opt_obj_role, Opt_obj_type,
526 Opt_subj_user, Opt_subj_role, Opt_subj_type, 530 Opt_subj_user, Opt_subj_role, Opt_subj_type,
527 Opt_func, Opt_mask, Opt_fsmagic, 531 Opt_func, Opt_mask, Opt_fsmagic,
@@ -538,6 +542,8 @@ static match_table_t policy_tokens = {
538 {Opt_appraise, "appraise"}, 542 {Opt_appraise, "appraise"},
539 {Opt_dont_appraise, "dont_appraise"}, 543 {Opt_dont_appraise, "dont_appraise"},
540 {Opt_audit, "audit"}, 544 {Opt_audit, "audit"},
545 {Opt_hash, "hash"},
546 {Opt_dont_hash, "dont_hash"},
541 {Opt_obj_user, "obj_user=%s"}, 547 {Opt_obj_user, "obj_user=%s"},
542 {Opt_obj_role, "obj_role=%s"}, 548 {Opt_obj_role, "obj_role=%s"},
543 {Opt_obj_type, "obj_type=%s"}, 549 {Opt_obj_type, "obj_type=%s"},
@@ -671,6 +677,22 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
671 677
672 entry->action = AUDIT; 678 entry->action = AUDIT;
673 break; 679 break;
680 case Opt_hash:
681 ima_log_string(ab, "action", "hash");
682
683 if (entry->action != UNKNOWN)
684 result = -EINVAL;
685
686 entry->action = HASH;
687 break;
688 case Opt_dont_hash:
689 ima_log_string(ab, "action", "dont_hash");
690
691 if (entry->action != UNKNOWN)
692 result = -EINVAL;
693
694 entry->action = DONT_HASH;
695 break;
674 case Opt_func: 696 case Opt_func:
675 ima_log_string(ab, "func", args[0].from); 697 ima_log_string(ab, "func", args[0].from);
676 698
@@ -743,7 +765,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
743 case Opt_fsuuid: 765 case Opt_fsuuid:
744 ima_log_string(ab, "fsuuid", args[0].from); 766 ima_log_string(ab, "fsuuid", args[0].from);
745 767
746 if (uuid_is_null(&entry->fsuuid)) { 768 if (!uuid_is_null(&entry->fsuuid)) {
747 result = -EINVAL; 769 result = -EINVAL;
748 break; 770 break;
749 } 771 }
@@ -1040,6 +1062,10 @@ int ima_policy_show(struct seq_file *m, void *v)
1040 seq_puts(m, pt(Opt_dont_appraise)); 1062 seq_puts(m, pt(Opt_dont_appraise));
1041 if (entry->action & AUDIT) 1063 if (entry->action & AUDIT)
1042 seq_puts(m, pt(Opt_audit)); 1064 seq_puts(m, pt(Opt_audit));
1065 if (entry->action & HASH)
1066 seq_puts(m, pt(Opt_hash));
1067 if (entry->action & DONT_HASH)
1068 seq_puts(m, pt(Opt_dont_hash));
1043 1069
1044 seq_puts(m, " "); 1070 seq_puts(m, " ");
1045 1071
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 7412d0291ab9..30db39b23804 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -377,8 +377,7 @@ int ima_restore_measurement_list(loff_t size, void *buf)
377 break; 377 break;
378 378
379 if (hdr[HDR_TEMPLATE_NAME].len >= MAX_TEMPLATE_NAME_LEN) { 379 if (hdr[HDR_TEMPLATE_NAME].len >= MAX_TEMPLATE_NAME_LEN) {
380 pr_err("attempting to restore a template name \ 380 pr_err("attempting to restore a template name that is too long\n");
381 that is too long\n");
382 ret = -EINVAL; 381 ret = -EINVAL;
383 break; 382 break;
384 } 383 }
@@ -389,8 +388,8 @@ int ima_restore_measurement_list(loff_t size, void *buf)
389 template_name[hdr[HDR_TEMPLATE_NAME].len] = 0; 388 template_name[hdr[HDR_TEMPLATE_NAME].len] = 0;
390 389
391 if (strcmp(template_name, "ima") == 0) { 390 if (strcmp(template_name, "ima") == 0) {
392 pr_err("attempting to restore an unsupported \ 391 pr_err("attempting to restore an unsupported template \"%s\" failed\n",
393 template \"%s\" failed\n", template_name); 392 template_name);
394 ret = -EINVAL; 393 ret = -EINVAL;
395 break; 394 break;
396 } 395 }
@@ -410,8 +409,8 @@ int ima_restore_measurement_list(loff_t size, void *buf)
410 &(template_desc->fields), 409 &(template_desc->fields),
411 &(template_desc->num_fields)); 410 &(template_desc->num_fields));
412 if (ret < 0) { 411 if (ret < 0) {
413 pr_err("attempting to restore the template fmt \"%s\" \ 412 pr_err("attempting to restore the template fmt \"%s\" failed\n",
414 failed\n", template_desc->fmt); 413 template_desc->fmt);
415 ret = -EINVAL; 414 ret = -EINVAL;
416 break; 415 break;
417 } 416 }