lsm:    [[subj_user=] [subj_role=] [subj_type=]
                                 [obj_user=] [obj_role=] [obj_type=]]
                        option: [[appraise_type=]] [template=] [permit_directio]
+                               [appraise_flag=]
                base:   func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
                                [FIRMWARE_CHECK]
                                [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
                        fowner:= decimal value
                lsm:    are LSM specific
                option: appraise_type:= [imasig] [imasig|modsig]
+                       appraise_flag:= [check_blacklist]
+                       Currently, blacklist check is only for files signed with appended
+                       signature.
                        template:= name of a defined IMA template type
                        (eg, ima-ng). Only valid when action is "measure".
                        pcr:= decimal value
 
 #define IMA_APPRAISE_KEXEC     0x40
 
 #ifdef CONFIG_IMA_APPRAISE
+int ima_check_blacklist(struct integrity_iint_cache *iint,
+                       const struct modsig *modsig, int pcr);
 int ima_appraise_measurement(enum ima_hooks func,
                             struct integrity_iint_cache *iint,
                             struct file *file, const unsigned char *filename,
                   struct evm_ima_xattr_data **xattr_value);
 
 #else
+static inline int ima_check_blacklist(struct integrity_iint_cache *iint,
+                                     const struct modsig *modsig, int pcr)
+{
+       return 0;
+}
+
 static inline int ima_appraise_measurement(enum ima_hooks func,
                                           struct integrity_iint_cache *iint,
                                           struct file *file,
 
 #include <linux/magic.h>
 #include <linux/ima.h>
 #include <linux/evm.h>
+#include <keys/system_keyring.h>
 
 #include "ima.h"
 
        return rc;
 }
 
+/*
+ * ima_check_blacklist - determine if the binary is blacklisted.
+ *
+ * Add the hash of the blacklisted binary to the measurement list, based
+ * on policy.
+ *
+ * Returns -EPERM if the hash is blacklisted.
+ */
+int ima_check_blacklist(struct integrity_iint_cache *iint,
+                       const struct modsig *modsig, int pcr)
+{
+       enum hash_algo hash_algo;
+       const u8 *digest = NULL;
+       u32 digestsize = 0;
+       int rc = 0;
+
+       if (!(iint->flags & IMA_CHECK_BLACKLIST))
+               return 0;
+
+       if (iint->flags & IMA_MODSIG_ALLOWED && modsig) {
+               ima_get_modsig_digest(modsig, &hash_algo, &digest, &digestsize);
+
+               rc = is_binary_blacklisted(digest, digestsize);
+               if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
+                       process_buffer_measurement(digest, digestsize,
+                                                  "blacklisted-hash", NONE,
+                                                  pcr);
+       }
+
+       return rc;
+}
+
 /*
  * ima_appraise_measurement - appraise file measurement
  *
 
                                      xattr_value, xattr_len, modsig, pcr,
                                      template_desc);
        if (rc == 0 && (action & IMA_APPRAISE_SUBMASK)) {
-               inode_lock(inode);
-               rc = ima_appraise_measurement(func, iint, file, pathname,
-                                             xattr_value, xattr_len, modsig);
-               inode_unlock(inode);
+               rc = ima_check_blacklist(iint, modsig, pcr);
+               if (rc != -EPERM) {
+                       inode_lock(inode);
+                       rc = ima_appraise_measurement(func, iint, file,
+                                                     pathname, xattr_value,
+                                                     xattr_len, modsig);
+                       inode_unlock(inode);
+               }
                if (!rc)
                        rc = mmap_violation_check(func, file, &pathbuf,
                                                  &pathname, filename);
 
        Opt_fsuuid, Opt_uid_eq, Opt_euid_eq, Opt_fowner_eq,
        Opt_uid_gt, Opt_euid_gt, Opt_fowner_gt,
        Opt_uid_lt, Opt_euid_lt, Opt_fowner_lt,
-       Opt_appraise_type, Opt_permit_directio,
-       Opt_pcr, Opt_template, Opt_err
+       Opt_appraise_type, Opt_appraise_flag,
+       Opt_permit_directio, Opt_pcr, Opt_template, Opt_err
 };
 
 static const match_table_t policy_tokens = {
        {Opt_euid_lt, "euid<%s"},
        {Opt_fowner_lt, "fowner<%s"},
        {Opt_appraise_type, "appraise_type=%s"},
+       {Opt_appraise_flag, "appraise_flag=%s"},
        {Opt_permit_directio, "permit_directio"},
        {Opt_pcr, "pcr=%s"},
        {Opt_template, "template=%s"},
                        else
                                result = -EINVAL;
                        break;
+               case Opt_appraise_flag:
+                       ima_log_string(ab, "appraise_flag", args[0].from);
+                       if (strstr(args[0].from, "blacklist"))
+                               entry->flags |= IMA_CHECK_BLACKLIST;
+                       break;
                case Opt_permit_directio:
                        entry->flags |= IMA_PERMIT_DIRECTIO;
                        break;
                else
                        seq_puts(m, "appraise_type=imasig ");
        }
+       if (entry->flags & IMA_CHECK_BLACKLIST)
+               seq_puts(m, "appraise_flag=check_blacklist ");
        if (entry->flags & IMA_PERMIT_DIRECTIO)
                seq_puts(m, "permit_directio ");
        rcu_read_unlock();
 
 #define EVM_IMMUTABLE_DIGSIG   0x08000000
 #define IMA_FAIL_UNVERIFIABLE_SIGS     0x10000000
 #define IMA_MODSIG_ALLOWED     0x20000000
+#define IMA_CHECK_BLACKLIST    0x40000000
 
 #define IMA_DO_MASK            (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
                                 IMA_HASH | IMA_APPRAISE_SUBMASK)