[fowner]]
                        lsm:    [[subj_user=] [subj_role=] [subj_type=]
                                 [obj_user=] [obj_role=] [obj_type=]]
-                       option: [[appraise_type=]]
+                       option: [[appraise_type=]] [permit_directio]
 
                base:   func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
                        mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
 
                            struct evm_ima_xattr_data **xattr_value,
                            int *xattr_len)
 {
+       const char *audit_cause = "failed";
        struct inode *inode = file_inode(file);
        const char *filename = file->f_dentry->d_name.name;
        int result = 0;
        if (!(iint->flags & IMA_COLLECTED)) {
                u64 i_version = file_inode(file)->i_version;
 
+               if (file->f_flags & O_DIRECT) {
+                       audit_cause = "failed(directio)";
+                       result = -EACCES;
+                       goto out;
+               }
+
                /* use default hash algorithm */
                hash.hdr.algo = ima_hash_algo;
 
                                result = -ENOMEM;
                }
        }
+out:
        if (result)
                integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode,
-                                   filename, "collect_data", "failed",
+                                   filename, "collect_data", audit_cause,
                                    result, 0);
        return result;
 }
 
                xattr_ptr = &xattr_value;
 
        rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len);
-       if (rc != 0)
+       if (rc != 0) {
+               if (file->f_flags & O_DIRECT)
+                       rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES;
                goto out_digsig;
+       }
 
        pathname = filename ?: ima_d_path(&file->f_path, &pathbuf);
 
 
        Opt_obj_user, Opt_obj_role, Opt_obj_type,
        Opt_subj_user, Opt_subj_role, Opt_subj_type,
        Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
-       Opt_appraise_type, Opt_fsuuid
+       Opt_appraise_type, Opt_fsuuid, Opt_permit_directio
 };
 
 static match_table_t policy_tokens = {
        {Opt_uid, "uid=%s"},
        {Opt_fowner, "fowner=%s"},
        {Opt_appraise_type, "appraise_type=%s"},
+       {Opt_permit_directio, "permit_directio"},
        {Opt_err, NULL}
 };
 
                        else
                                result = -EINVAL;
                        break;
+               case Opt_permit_directio:
+                       entry->flags |= IMA_PERMIT_DIRECTIO;
+                       break;
                case Opt_err:
                        ima_log_string(ab, "UNKNOWN", p);
                        result = -EINVAL;
 
 #define IMA_ACTION_FLAGS       0xff000000
 #define IMA_DIGSIG             0x01000000
 #define IMA_DIGSIG_REQUIRED    0x02000000
+#define IMA_PERMIT_DIRECTIO    0x04000000
 
 #define IMA_DO_MASK            (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
                                 IMA_APPRAISE_SUBMASK)