diff options
| author | Ingo Molnar <[email protected]> | 2014-11-12 15:09:01 +0100 | 
|---|---|---|
| committer | Ingo Molnar <[email protected]> | 2014-11-12 15:09:01 +0100 | 
| commit | 890ca861f868a10617029ffc87eae7d48ea6876c (patch) | |
| tree | 713383f4e3bbd94ddb9816a25e6b3911511908f1 /kernel/auditfilter.c | |
| parent | 03452d27c6cd9cebb59a6bb0fb6bd8557916c263 (diff) | |
| parent | 206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff) | |
Merge tag 'v3.18-rc4' into x86/cleanups, to refresh the tree before pulling new changes.
Signed-off-by: Ingo Molnar <[email protected]>
Diffstat (limited to 'kernel/auditfilter.c')
| -rw-r--r-- | kernel/auditfilter.c | 60 | 
1 files changed, 34 insertions, 26 deletions
| diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 8e9bc9c3dbb7..3598e13f2a65 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -71,6 +71,24 @@ static struct list_head audit_rules_list[AUDIT_NR_FILTERS] = {  DEFINE_MUTEX(audit_filter_mutex); +static void audit_free_lsm_field(struct audit_field *f) +{ +	switch (f->type) { +	case AUDIT_SUBJ_USER: +	case AUDIT_SUBJ_ROLE: +	case AUDIT_SUBJ_TYPE: +	case AUDIT_SUBJ_SEN: +	case AUDIT_SUBJ_CLR: +	case AUDIT_OBJ_USER: +	case AUDIT_OBJ_ROLE: +	case AUDIT_OBJ_TYPE: +	case AUDIT_OBJ_LEV_LOW: +	case AUDIT_OBJ_LEV_HIGH: +		kfree(f->lsm_str); +		security_audit_rule_free(f->lsm_rule); +	} +} +  static inline void audit_free_rule(struct audit_entry *e)  {  	int i; @@ -80,11 +98,8 @@ static inline void audit_free_rule(struct audit_entry *e)  	if (erule->watch)  		audit_put_watch(erule->watch);  	if (erule->fields) -		for (i = 0; i < erule->field_count; i++) { -			struct audit_field *f = &erule->fields[i]; -			kfree(f->lsm_str); -			security_audit_rule_free(f->lsm_rule); -		} +		for (i = 0; i < erule->field_count; i++) +			audit_free_lsm_field(&erule->fields[i]);  	kfree(erule->fields);  	kfree(erule->filterkey);  	kfree(e); @@ -106,7 +121,7 @@ static inline struct audit_entry *audit_init_entry(u32 field_count)  	if (unlikely(!entry))  		return NULL; -	fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL); +	fields = kcalloc(field_count, sizeof(*fields), GFP_KERNEL);  	if (unlikely(!fields)) {  		kfree(entry);  		return NULL; @@ -148,7 +163,7 @@ static inline int audit_to_inode(struct audit_krule *krule,  				 struct audit_field *f)  {  	if (krule->listnr != AUDIT_FILTER_EXIT || -	    krule->watch || krule->inode_f || krule->tree || +	    krule->inode_f || krule->watch || krule->tree ||  	    (f->op != Audit_equal && f->op != Audit_not_equal))  		return -EINVAL; @@ -160,7 +175,7 @@ static __u32 *classes[AUDIT_SYSCALL_CLASSES];  int __init audit_register_class(int class, unsigned *list)  { -	__u32 *p = kzalloc(AUDIT_BITMASK_SIZE * sizeof(__u32), GFP_KERNEL); +	__u32 *p = kcalloc(AUDIT_BITMASK_SIZE, sizeof(__u32), GFP_KERNEL);  	if (!p)  		return -ENOMEM;  	while (*list != ~0U) { @@ -422,10 +437,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,  		f->type = data->fields[i];  		f->val = data->values[i]; -		f->uid = INVALID_UID; -		f->gid = INVALID_GID; -		f->lsm_str = NULL; -		f->lsm_rule = NULL;  		/* Support legacy tests for a valid loginuid */  		if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) { @@ -1053,30 +1064,27 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,  	int err = 0;  	struct audit_entry *entry; +	entry = audit_data_to_entry(data, datasz); +	if (IS_ERR(entry)) +		return PTR_ERR(entry); +  	switch (type) {  	case AUDIT_ADD_RULE: -		entry = audit_data_to_entry(data, datasz); -		if (IS_ERR(entry)) -			return PTR_ERR(entry); -  		err = audit_add_rule(entry); -		audit_log_rule_change("add rule", &entry->rule, !err); -		if (err) -			audit_free_rule(entry); +		audit_log_rule_change("add_rule", &entry->rule, !err);  		break;  	case AUDIT_DEL_RULE: -		entry = audit_data_to_entry(data, datasz); -		if (IS_ERR(entry)) -			return PTR_ERR(entry); -  		err = audit_del_rule(entry); -		audit_log_rule_change("remove rule", &entry->rule, !err); -		audit_free_rule(entry); +		audit_log_rule_change("remove_rule", &entry->rule, !err);  		break;  	default: -		return -EINVAL; +		err = -EINVAL; +		WARN_ON(1);  	} +	if (err || type == AUDIT_DEL_RULE) +		audit_free_rule(entry); +  	return err;  } |