ima: re-evaluate file integrity on file metadata change
authorStefan Berger <stefanb@linux.ibm.com>
Fri, 23 Feb 2024 17:25:10 +0000 (12:25 -0500)
committerMimi Zohar <zohar@linux.ibm.com>
Tue, 9 Apr 2024 21:14:57 +0000 (17:14 -0400)
Force a file's integrity to be re-evaluated on file metadata change by
resetting both the IMA and EVM status flags.

Co-developed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
security/integrity/ima/ima_main.c

index 4b215d85c14bbcd2f65a99ad8d5289a8a89df8b9..f04f43af651c8e56754ab3e32cde9adc6d18915b 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ima.h>
 #include <linux/fs.h>
 #include <linux/iversion.h>
+#include <linux/evm.h>
 
 #include "ima.h"
 
@@ -211,6 +212,7 @@ static int process_measurement(struct file *file, const struct cred *cred,
        struct inode *real_inode, *inode = file_inode(file);
        struct ima_iint_cache *iint = NULL;
        struct ima_template_desc *template_desc = NULL;
+       struct inode *metadata_inode;
        char *pathbuf = NULL;
        char filename[NAME_MAX];
        const char *pathname = NULL;
@@ -286,7 +288,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
        }
 
        /*
-        * On stacked filesystems, detect and re-evaluate file data changes.
+        * On stacked filesystems, detect and re-evaluate file data and
+        * metadata changes.
         */
        real_inode = d_real_inode(file_dentry(file));
        if (real_inode != inode &&
@@ -297,6 +300,15 @@ static int process_measurement(struct file *file, const struct cred *cred,
                        iint->flags &= ~IMA_DONE_MASK;
                        iint->measured_pcrs = 0;
                }
+
+               /*
+                * Reset the EVM status when metadata changed.
+                */
+               metadata_inode = d_inode(d_real(file_dentry(file),
+                                        D_REAL_METADATA));
+               if (evm_metadata_changed(inode, metadata_inode))
+                       iint->flags &= ~(IMA_APPRAISED |
+                                        IMA_APPRAISED_SUBMASK);
        }
 
        /* Determine if already appraised/measured based on bitmask