]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - security/integrity/ima/ima_main.c
ima: delay template descriptor lookup until use
[mirror_ubuntu-bionic-kernel.git] / security / integrity / ima / ima_main.c
index dcc98cf542d83fb4768ff3bd2ec113c204c7ecb6..f474c608fa1194ebde04e21f2bdabc5be64c5d4a 100644 (file)
@@ -81,7 +81,6 @@ static void ima_rdwr_violation_check(struct file *file)
 {
        struct inode *inode = file_inode(file);
        fmode_t mode = file->f_mode;
-       int must_measure;
        bool send_tomtou = false, send_writers = false;
        char *pathbuf = NULL;
        const char *pathname;
@@ -89,23 +88,20 @@ static void ima_rdwr_violation_check(struct file *file)
        if (!S_ISREG(inode->i_mode) || !ima_initialized)
                return;
 
-       mutex_lock(&inode->i_mutex);    /* file metadata: permissions, xattr */
-
        if (mode & FMODE_WRITE) {
-               if (atomic_read(&inode->i_readcount) && IS_IMA(inode))
-                       send_tomtou = true;
-               goto out;
+               if (atomic_read(&inode->i_readcount) && IS_IMA(inode)) {
+                       struct integrity_iint_cache *iint;
+                       iint = integrity_iint_find(inode);
+                       /* IMA_MEASURE is set from reader side */
+                       if (iint && (iint->flags & IMA_MEASURE))
+                               send_tomtou = true;
+               }
+       } else {
+               if ((atomic_read(&inode->i_writecount) > 0) &&
+                   ima_must_measure(inode, MAY_READ, FILE_CHECK))
+                       send_writers = true;
        }
 
-       must_measure = ima_must_measure(inode, MAY_READ, FILE_CHECK);
-       if (!must_measure)
-               goto out;
-
-       if (atomic_read(&inode->i_writecount) > 0)
-               send_writers = true;
-out:
-       mutex_unlock(&inode->i_mutex);
-
        if (!send_tomtou && !send_writers)
                return;
 
@@ -163,7 +159,7 @@ static int process_measurement(struct file *file, const char *filename,
 {
        struct inode *inode = file_inode(file);
        struct integrity_iint_cache *iint;
-       struct ima_template_desc *template_desc = ima_template_desc_current();
+       struct ima_template_desc *template_desc;
        char *pathbuf = NULL;
        const char *pathname = NULL;
        int rc = -ENOMEM, action, must_appraise, _func;
@@ -207,6 +203,7 @@ static int process_measurement(struct file *file, const char *filename,
                goto out_digsig;
        }
 
+       template_desc = ima_template_desc_current();
        if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) {
                if (action & IMA_APPRAISE_SUBMASK)
                        xattr_ptr = &xattr_value;