ima: Fix use-after-free on a dentry's dname.name
[linux-2.6-block.git] / security / integrity / ima / ima_api.c
index b37d043d5748c74b986fb1a4dd281344a1036643..1856981e33df3bbbccfcd278bb4ce42f6f13e1b3 100644 (file)
@@ -245,8 +245,8 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file,
        const char *audit_cause = "failed";
        struct inode *inode = file_inode(file);
        struct inode *real_inode = d_real_inode(file_dentry(file));
-       const char *filename = file->f_path.dentry->d_name.name;
        struct ima_max_digest_data hash;
+       struct name_snapshot filename;
        struct kstat stat;
        int result = 0;
        int length;
@@ -317,9 +317,13 @@ out:
                if (file->f_flags & O_DIRECT)
                        audit_cause = "failed(directio)";
 
+               take_dentry_name_snapshot(&filename, file->f_path.dentry);
+
                integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
-                                   filename, "collect_data", audit_cause,
-                                   result, 0);
+                                   filename.name.name, "collect_data",
+                                   audit_cause, result, 0);
+
+               release_dentry_name_snapshot(&filename);
        }
        return result;
 }
@@ -432,6 +436,7 @@ out:
  */
 const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
 {
+       struct name_snapshot filename;
        char *pathname = NULL;
 
        *pathbuf = __getname();
@@ -445,7 +450,10 @@ const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
        }
 
        if (!pathname) {
-               strscpy(namebuf, path->dentry->d_name.name, NAME_MAX);
+               take_dentry_name_snapshot(&filename, path->dentry);
+               strscpy(namebuf, filename.name.name, NAME_MAX);
+               release_dentry_name_snapshot(&filename);
+
                pathname = namebuf;
        }