[obj_user=] [obj_role=] [obj_type=]]
                        option: [[appraise_type=]] [permit_directio]
 
-               base:   func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
+               base:   func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
                                [FIRMWARE_CHECK]
                                [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
                        mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
 
        iint->ima_mmap_status = INTEGRITY_UNKNOWN;
        iint->ima_bprm_status = INTEGRITY_UNKNOWN;
        iint->ima_read_status = INTEGRITY_UNKNOWN;
+       iint->ima_creds_status = INTEGRITY_UNKNOWN;
        iint->evm_status = INTEGRITY_UNKNOWN;
        iint->measured_pcrs = 0;
        kmem_cache_free(iint_cache, iint);
        iint->ima_mmap_status = INTEGRITY_UNKNOWN;
        iint->ima_bprm_status = INTEGRITY_UNKNOWN;
        iint->ima_read_status = INTEGRITY_UNKNOWN;
+       iint->ima_creds_status = INTEGRITY_UNKNOWN;
        iint->evm_status = INTEGRITY_UNKNOWN;
        mutex_init(&iint->mutex);
 }
 
        hook(FILE_CHECK)                \
        hook(MMAP_CHECK)                \
        hook(BPRM_CHECK)                \
+       hook(CREDS_CHECK)               \
        hook(POST_SETATTR)              \
        hook(MODULE_CHECK)              \
        hook(FIRMWARE_CHECK)            \
 };
 
 /* LIM API function definitions */
-int ima_get_action(struct inode *inode, int mask,
-                  enum ima_hooks func, int *pcr);
+int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
+                  int mask, enum ima_hooks func, int *pcr);
 int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func);
 int ima_collect_measurement(struct integrity_iint_cache *iint,
                            struct file *file, void *buf, loff_t size,
 const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
 
 /* IMA policy related functions */
-int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
-                    int flags, int *pcr);
+int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
+                    enum ima_hooks func, int mask, int flags, int *pcr);
 void ima_init_policy(void);
 void ima_update_policy(void);
 void ima_update_policy_flag(void);
 
 /**
  * ima_get_action - appraise & measure decision based on policy.
  * @inode: pointer to inode to measure
+ * @cred: pointer to credentials structure to validate
+ * @secid: secid of the task being validated
  * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,
  *        MAY_APPEND)
  * @func: caller identifier
  * The policy is defined in terms of keypairs:
  *             subj=, obj=, type=, func=, mask=, fsmagic=
  *     subj,obj, and type: are LSM specific.
- *     func: FILE_CHECK | BPRM_CHECK | MMAP_CHECK | MODULE_CHECK
+ *     func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK
  *     mask: contains the permission mask
  *     fsmagic: hex value
  *
  * Returns IMA_MEASURE, IMA_APPRAISE mask.
  *
  */
-int ima_get_action(struct inode *inode, int mask, enum ima_hooks func, int *pcr)
+int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
+                  int mask, enum ima_hooks func, int *pcr)
 {
        int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH;
 
        flags &= ima_policy_flag;
 
-       return ima_match_policy(inode, func, mask, flags, pcr);
+       return ima_match_policy(inode, cred, secid, func, mask, flags, pcr);
 }
 
 /*
 
  */
 int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func)
 {
+       u32 secid;
+
        if (!ima_appraise)
                return 0;
 
-       return ima_match_policy(inode, func, mask, IMA_APPRAISE | IMA_HASH,
-                               NULL);
+       security_task_getsecid(current, &secid);
+       return ima_match_policy(inode, current_cred(), secid, func, mask,
+                               IMA_APPRAISE | IMA_HASH, NULL);
 }
 
 static int ima_fix_xattr(struct dentry *dentry,
                return iint->ima_mmap_status;
        case BPRM_CHECK:
                return iint->ima_bprm_status;
+       case CREDS_CHECK:
+               return iint->ima_creds_status;
        case FILE_CHECK:
        case POST_SETATTR:
                return iint->ima_file_status;
        case BPRM_CHECK:
                iint->ima_bprm_status = status;
                break;
+       case CREDS_CHECK:
+               iint->ima_creds_status = status;
        case FILE_CHECK:
        case POST_SETATTR:
                iint->ima_file_status = status;
        case BPRM_CHECK:
                iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED);
                break;
+       case CREDS_CHECK:
+               iint->flags |= (IMA_CREDS_APPRAISED | IMA_APPRAISED);
+               break;
        case FILE_CHECK:
        case POST_SETATTR:
                iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
 
        ima_check_last_writer(iint, inode, file);
 }
 
-static int process_measurement(struct file *file, char *buf, loff_t size,
-                              int mask, enum ima_hooks func, int opened)
+static int process_measurement(struct file *file, const struct cred *cred,
+                              u32 secid, char *buf, loff_t size, int mask,
+                              enum ima_hooks func, int opened)
 {
        struct inode *inode = file_inode(file);
        struct integrity_iint_cache *iint = NULL;
         * bitmask based on the appraise/audit/measurement policy.
         * Included is the appraise submask.
         */
-       action = ima_get_action(inode, mask, func, &pcr);
+       action = ima_get_action(inode, cred, secid, mask, func, &pcr);
        violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) &&
                           (ima_policy_flag & IMA_MEASURE));
        if (!action && !violation_check)
  */
 int ima_file_mmap(struct file *file, unsigned long prot)
 {
-       if (file && (prot & PROT_EXEC))
-               return process_measurement(file, NULL, 0, MAY_EXEC,
-                                          MMAP_CHECK, 0);
+       u32 secid;
+
+       if (file && (prot & PROT_EXEC)) {
+               security_task_getsecid(current, &secid);
+               return process_measurement(file, current_cred(), secid, NULL,
+                                          0, MAY_EXEC, MMAP_CHECK, 0);
+       }
+
        return 0;
 }
 
  */
 int ima_bprm_check(struct linux_binprm *bprm)
 {
-       return process_measurement(bprm->file, NULL, 0, MAY_EXEC,
-                                  BPRM_CHECK, 0);
+       int ret;
+       u32 secid;
+
+       security_task_getsecid(current, &secid);
+       ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0,
+                                 MAY_EXEC, BPRM_CHECK, 0);
+       if (ret)
+               return ret;
+
+       security_cred_getsecid(bprm->cred, &secid);
+       return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
+                                  MAY_EXEC, CREDS_CHECK, 0);
 }
 
 /**
  */
 int ima_file_check(struct file *file, int mask, int opened)
 {
-       return process_measurement(file, NULL, 0,
+       u32 secid;
+
+       security_task_getsecid(current, &secid);
+       return process_measurement(file, current_cred(), secid, NULL, 0,
                                   mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
                                           MAY_APPEND), FILE_CHECK, opened);
 }
                       enum kernel_read_file_id read_id)
 {
        enum ima_hooks func;
+       u32 secid;
 
        if (!file && read_id == READING_FIRMWARE) {
                if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
        }
 
        func = read_idmap[read_id] ?: FILE_CHECK;
-       return process_measurement(file, buf, size, MAY_READ, func, 0);
+       security_task_getsecid(current, &secid);
+       return process_measurement(file, current_cred(), secid, buf, size,
+                                  MAY_READ, func, 0);
 }
 
 static int __init init_ima(void)
 
  * ima_match_rules - determine whether an inode matches the measure rule.
  * @rule: a pointer to a rule
  * @inode: a pointer to an inode
+ * @cred: a pointer to a credentials structure for user validation
+ * @secid: the secid of the task to be validated
  * @func: LIM hook identifier
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
  *
  * Returns true on rule match, false on failure.
  */
 static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
+                           const struct cred *cred, u32 secid,
                            enum ima_hooks func, int mask)
 {
-       struct task_struct *tsk = current;
-       const struct cred *cred = current_cred();
        int i;
 
        if ((rule->flags & IMA_FUNC) &&
                return false;
        for (i = 0; i < MAX_LSM_RULES; i++) {
                int rc = 0;
-               u32 osid, sid;
+               u32 osid;
                int retried = 0;
 
                if (!rule->lsm[i].rule)
                case LSM_SUBJ_USER:
                case LSM_SUBJ_ROLE:
                case LSM_SUBJ_TYPE:
-                       security_task_getsecid(tsk, &sid);
-                       rc = security_filter_rule_match(sid,
+                       rc = security_filter_rule_match(secid,
                                                        rule->lsm[i].type,
                                                        Audit_equal,
                                                        rule->lsm[i].rule,
                return IMA_MMAP_APPRAISE;
        case BPRM_CHECK:
                return IMA_BPRM_APPRAISE;
+       case CREDS_CHECK:
+               return IMA_CREDS_APPRAISE;
        case FILE_CHECK:
        case POST_SETATTR:
                return IMA_FILE_APPRAISE;
 /**
  * ima_match_policy - decision based on LSM and other conditions
  * @inode: pointer to an inode for which the policy decision is being made
+ * @cred: pointer to a credentials structure for which the policy decision is
+ *        being made
+ * @secid: LSM secid of the task to be validated
  * @func: IMA hook identifier
  * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
  * @pcr: set the pcr to extend
  * list when walking it.  Reads are many orders of magnitude more numerous
  * than writes so ima_match_policy() is classical RCU candidate.
  */
-int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
-                    int flags, int *pcr)
+int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid,
+                    enum ima_hooks func, int mask, int flags, int *pcr)
 {
        struct ima_rule_entry *entry;
        int action = 0, actmask = flags | (flags << 1);
                if (!(entry->action & actmask))
                        continue;
 
-               if (!ima_match_rules(entry, inode, func, mask))
+               if (!ima_match_rules(entry, inode, cred, secid, func, mask))
                        continue;
 
                action |= entry->flags & IMA_ACTION_FLAGS;
                                entry->func = MMAP_CHECK;
                        else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
                                entry->func = BPRM_CHECK;
+                       else if (strcmp(args[0].from, "CREDS_CHECK") == 0)
+                               entry->func = CREDS_CHECK;
                        else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") ==
                                 0)
                                entry->func = KEXEC_KERNEL_CHECK;
 
 #define IMA_BPRM_APPRAISED     0x00020000
 #define IMA_READ_APPRAISE      0x00040000
 #define IMA_READ_APPRAISED     0x00080000
+#define IMA_CREDS_APPRAISE     0x00100000
+#define IMA_CREDS_APPRAISED    0x00200000
 #define IMA_APPRAISE_SUBMASK   (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \
-                                IMA_BPRM_APPRAISE | IMA_READ_APPRAISE)
+                                IMA_BPRM_APPRAISE | IMA_READ_APPRAISE | \
+                                IMA_CREDS_APPRAISE)
 #define IMA_APPRAISED_SUBMASK  (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
-                                IMA_BPRM_APPRAISED | IMA_READ_APPRAISED)
+                                IMA_BPRM_APPRAISED | IMA_READ_APPRAISED | \
+                                IMA_CREDS_APPRAISED)
 
 /* iint cache atomic_flags */
 #define IMA_CHANGE_XATTR       0
        enum integrity_status ima_mmap_status:4;
        enum integrity_status ima_bprm_status:4;
        enum integrity_status ima_read_status:4;
+       enum integrity_status ima_creds_status:4;
        enum integrity_status evm_status:4;
        struct ima_digest_data *ima_hash;
 };