summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/integrity/ima/ima_api.c6
-rw-r--r--security/integrity/ima/ima_appraise.c1
-rw-r--r--security/integrity/ima/ima_main.c7
3 files changed, 11 insertions, 3 deletions
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 8363ba384992..9df26a2b75ba 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -266,7 +266,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
xattr_len, NULL};
int violation = 0;
- if (iint->flags & IMA_MEASURED)
+ if (iint->measured_pcrs & (0x1 << pcr))
return;
result = ima_alloc_init_template(&event_data, &entry);
@@ -277,8 +277,10 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
}
result = ima_store_template(entry, violation, inode, filename, pcr);
- if (!result || result == -EEXIST)
+ if (!result || result == -EEXIST) {
iint->flags |= IMA_MEASURED;
+ iint->measured_pcrs |= (0x1 << pcr);
+ }
if (result < 0)
ima_free_template_entry(entry);
}
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index fe8e92360d77..4b9b4a4e1b89 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -370,6 +370,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
return;
iint->flags &= ~IMA_DONE_MASK;
+ iint->measured_pcrs = 0;
if (digsig)
iint->flags |= IMA_DIGSIG;
return;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 3627afdc932e..596ef616ac21 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -125,6 +125,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
if ((iint->version != inode->i_version) ||
(iint->flags & IMA_NEW_FILE)) {
iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
+ iint->measured_pcrs = 0;
if (iint->flags & IMA_APPRAISE)
ima_update_xattr(iint, file);
}
@@ -210,7 +211,11 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
*/
iint->flags |= action;
action &= IMA_DO_MASK;
- action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
+ action &= ~((iint->flags & (IMA_DONE_MASK ^ IMA_MEASURED)) >> 1);
+
+ /* If target pcr is already measured, unset IMA_MEASURE action */
+ if ((action & IMA_MEASURE) && (iint->measured_pcrs & (0x1 << pcr)))
+ action ^= IMA_MEASURE;
/* Nothing to do, just return existing appraised status */
if (!action) {