Commit a756024e authored by Roberto Sassu's avatar Roberto Sassu Committed by Mimi Zohar

ima: added ima_policy_flag variable

This patch introduces the new variable 'ima_policy_flag', whose bits
are set depending on the action of the current policy rules. Only the
flags IMA_MEASURE, IMA_APPRAISE and IMA_AUDIT are set.

The new variable will be used to improve performance by skipping the
unnecessary execution of IMA code if the policy does not contain rules
with the above actions.

Changes in v6 (Roberto Sassu)
* do not check 'ima_initialized' before calling ima_update_policy_flag()
  in ima_update_policy() (suggested by Dmitry)
* calling ima_update_policy_flag() moved to init_ima to co-locate with
  ima_initialized (Dmitry)
* add/revise comments (Mimi)

Changes in v5 (Roberto Sassu)
* reset IMA_APPRAISE flag in 'ima_policy_flag' if 'ima_appraise' is set
  to zero (reported by Dmitry)
* update 'ima_policy_flag' only if IMA initialization is successful
  (suggested by Mimi and Dmitry)
* check 'ima_policy_flag' instead of 'ima_initialized'
  (suggested by Mimi and Dmitry)
Signed-off-by: default avatarRoberto Sassu <roberto.sassu@polito.it>
Signed-off-by: default avatarDmitry Kasatkin <d.kasatkin@samsung.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent be39ffc2
...@@ -43,6 +43,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; ...@@ -43,6 +43,9 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 };
#define IMA_TEMPLATE_IMA_NAME "ima" #define IMA_TEMPLATE_IMA_NAME "ima"
#define IMA_TEMPLATE_IMA_FMT "d|n" #define IMA_TEMPLATE_IMA_FMT "d|n"
/* current content of the policy */
extern int ima_policy_flag;
/* set during initialization */ /* set during initialization */
extern int ima_initialized; extern int ima_initialized;
extern int ima_used_chip; extern int ima_used_chip;
...@@ -153,6 +156,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, ...@@ -153,6 +156,7 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
int flags); int flags);
void ima_init_policy(void); void ima_init_policy(void);
void ima_update_policy(void); void ima_update_policy(void);
void ima_update_policy_flag(void);
ssize_t ima_parse_add_rule(char *); ssize_t ima_parse_add_rule(char *);
void ima_delete_rules(void); void ima_delete_rules(void);
......
...@@ -318,7 +318,7 @@ void ima_inode_post_setattr(struct dentry *dentry) ...@@ -318,7 +318,7 @@ void ima_inode_post_setattr(struct dentry *dentry)
struct integrity_iint_cache *iint; struct integrity_iint_cache *iint;
int must_appraise, rc; 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) || !inode->i_op->removexattr)
return; return;
...@@ -356,7 +356,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig) ...@@ -356,7 +356,7 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig)
{ {
struct integrity_iint_cache *iint; 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; return;
iint = integrity_iint_find(inode); iint = integrity_iint_find(inode);
......
...@@ -85,7 +85,7 @@ static void ima_rdwr_violation_check(struct file *file) ...@@ -85,7 +85,7 @@ static void ima_rdwr_violation_check(struct file *file)
char *pathbuf = NULL; char *pathbuf = NULL;
const char *pathname; const char *pathname;
if (!S_ISREG(inode->i_mode) || !ima_initialized) if (!S_ISREG(inode->i_mode) || !(ima_policy_flag & IMA_MEASURE))
return; return;
if (mode & FMODE_WRITE) { if (mode & FMODE_WRITE) {
...@@ -168,7 +168,7 @@ static int process_measurement(struct file *file, int mask, int function, ...@@ -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; struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL;
int xattr_len = 0; int xattr_len = 0;
if (!ima_initialized || !S_ISREG(inode->i_mode)) if (!ima_policy_flag || !S_ISREG(inode->i_mode))
return 0; return 0;
/* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action /* Return an IMA_MEASURE, IMA_APPRAISE, IMA_AUDIT action
...@@ -334,8 +334,10 @@ static int __init init_ima(void) ...@@ -334,8 +334,10 @@ static int __init init_ima(void)
hash_setup(CONFIG_IMA_DEFAULT_HASH); hash_setup(CONFIG_IMA_DEFAULT_HASH);
error = ima_init(); error = ima_init();
if (!error) if (!error) {
ima_initialized = 1; ima_initialized = 1;
ima_update_policy_flag();
}
return error; return error;
} }
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#define DONT_APPRAISE 0x0008 #define DONT_APPRAISE 0x0008
#define AUDIT 0x0040 #define AUDIT 0x0040
int ima_policy_flag;
#define MAX_LSM_RULES 6 #define MAX_LSM_RULES 6
enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE, enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_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, ...@@ -295,6 +297,26 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
return action; 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. * ima_init_policy - initialize the default measure rules.
* *
...@@ -341,6 +363,7 @@ void ima_update_policy(void) ...@@ -341,6 +363,7 @@ void ima_update_policy(void)
if (ima_rules == &ima_default_rules) { if (ima_rules == &ima_default_rules) {
ima_rules = &ima_policy_rules; ima_rules = &ima_policy_rules;
ima_update_policy_flag();
cause = "complete"; cause = "complete";
result = 0; result = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment