diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index d61680dcd3650705d8213a984833a30eea8ac62e..8ee997dff13937521157d02c6aac27b25903b46f 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -43,6 +43,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; #define IMA_TEMPLATE_IMA_NAME "ima" #define IMA_TEMPLATE_IMA_FMT "d|n" +/* current content of the policy */ +extern int ima_policy_flag; + /* set during initialization */ extern int ima_initialized; extern int ima_used_chip; @@ -153,6 +156,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, int flags); void ima_init_policy(void); void ima_update_policy(void); +void ima_update_policy_flag(void); ssize_t ima_parse_add_rule(char *); void ima_delete_rules(void); diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 2dc13fbb7e91cc74e93ec0cb595057295a2a57da..922685483bd3625355af6202bb435728ac62c11f 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -318,7 +318,7 @@ void ima_inode_post_setattr(struct dentry *dentry) struct integrity_iint_cache *iint; int must_appraise, rc; - if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode) + if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode) || !inode->i_op->removexattr) return; @@ -356,7 +356,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig) { struct integrity_iint_cache *iint; - if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)) + if (!(ima_policy_flag & IMA_APPRAISE) || !S_ISREG(inode->i_mode)) return; iint = integrity_iint_find(inode); diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index ed7d9fa4f53645832f02e3837070e12bc16ee588..2191b36ad1dadb95819d967b9986611a1da04b30 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -85,7 +85,7 @@ static void ima_rdwr_violation_check(struct file *file) char *pathbuf = NULL; const char *pathname; - if (!S_ISREG(inode->i_mode) || !ima_initialized) + if (!S_ISREG(inode->i_mode) || !(ima_policy_flag & IMA_MEASURE)) return; if (mode & FMODE_WRITE) { @@ -168,7 +168,7 @@ static int process_measurement(struct file *file, int mask, int function, struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; int xattr_len = 0; - if (!ima_initialized || !S_ISREG(inode->i_mode)) + if (!ima_policy_flag || !S_ISREG(inode->i_mode)) return 0; /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action @@ -334,8 +334,10 @@ static int __init init_ima(void) hash_setup(CONFIG_IMA_DEFAULT_HASH); error = ima_init(); - if (!error) + if (!error) { ima_initialized = 1; + ima_update_policy_flag(); + } return error; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 07099a8bc2835d8a8bb0ef3f7ec2f826796fd270..cdc620b2152f9431ddd9e73e651ecc4587802939 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -35,6 +35,8 @@ #define DONT_APPRAISE 0x0008 #define AUDIT 0x0040 +int ima_policy_flag; + #define MAX_LSM_RULES 6 enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE @@ -295,6 +297,26 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, return action; } +/* + * Initialize the ima_policy_flag variable based on the currently + * loaded policy. Based on this flag, the decision to short circuit + * out of a function or not call the function in the first place + * can be made earlier. + */ +void ima_update_policy_flag(void) +{ + struct ima_rule_entry *entry; + + ima_policy_flag = 0; + list_for_each_entry(entry, ima_rules, list) { + if (entry->action & IMA_DO_MASK) + ima_policy_flag |= entry->action; + } + + if (!ima_appraise) + ima_policy_flag &= ~IMA_APPRAISE; +} + /** * ima_init_policy - initialize the default measure rules. * @@ -341,6 +363,7 @@ void ima_update_policy(void) if (ima_rules == &ima_default_rules) { ima_rules = &ima_policy_rules; + ima_update_policy_flag(); cause = "complete"; result = 0; }