From e7df61f4d1ddb7fdd654dde6cd40f7cc398c3932 Mon Sep 17 00:00:00 2001 From: Burn Alting Date: Fri, 4 Apr 2014 16:00:38 +1100 Subject: audit: invalid op= values for rules Various audit events dealing with adding, removing and updating rules result in invalid values set for the op keys which result in embedded spaces in op= values. The invalid values are op="add rule" set in kernel/auditfilter.c op="remove rule" set in kernel/auditfilter.c op="remove rule" set in kernel/audit_tree.c op="updated rules" set in kernel/audit_watch.c op="remove rule" set in kernel/audit_watch.c Replace the space in the above values with an underscore character ('_'). Coded-by: Burn Alting Signed-off-by: Richard Guy Briggs --- kernel/auditfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 8e9bc9c3dbb7..b65a138250b8 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1060,7 +1060,7 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, return PTR_ERR(entry); err = audit_add_rule(entry); - audit_log_rule_change("add rule", &entry->rule, !err); + audit_log_rule_change("add_rule", &entry->rule, !err); if (err) audit_free_rule(entry); break; @@ -1070,7 +1070,7 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, return PTR_ERR(entry); err = audit_del_rule(entry); - audit_log_rule_change("remove rule", &entry->rule, !err); + audit_log_rule_change("remove_rule", &entry->rule, !err); audit_free_rule(entry); break; default: -- cgit v1.2.3 From 219ca39427bf6c46c4e1473493e33bc00635e99b Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 26 Mar 2014 07:26:47 -0400 Subject: audit: use union for audit_field values since they are mutually exclusive Since only one of val, uid, gid and lsm* are used at any given time, combine them to reduce the size of the struct audit_field. Signed-off-by: Richard Guy Briggs --- include/linux/audit.h | 14 +++++++++----- kernel/auditfilter.c | 29 ++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/include/linux/audit.h b/include/linux/audit.h index 1ae00891aff9..36dffeccebdb 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -66,12 +66,16 @@ struct audit_krule { struct audit_field { u32 type; - u32 val; - kuid_t uid; - kgid_t gid; + union { + u32 val; + kuid_t uid; + kgid_t gid; + struct { + char *lsm_str; + void *lsm_rule; + }; + }; u32 op; - char *lsm_str; - void *lsm_rule; }; extern int is_audit_feature_set(int which); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index b65a138250b8..40ed9813d4b2 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); @@ -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)) { -- cgit v1.2.3 From 3639f17068ed40e4e208a6e218481d49817bbd56 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Thu, 2 Oct 2014 22:05:18 -0400 Subject: audit: put rule existence check in canonical order Use same rule existence check order as audit_make_tree(), audit_to_watch(), update_lsm_rule() for legibility. Signed-off-by: Richard Guy Briggs Signed-off-by: Eric Paris --- kernel/auditfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 40ed9813d4b2..4a11697cf5b8 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -163,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; -- cgit v1.2.3 From 739c95038e68d364b01c0fc6f8fb8e47b1c1e979 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 10 Oct 2014 15:05:21 -0400 Subject: audit: WARN if audit_rule_change called illegally Signed-off-by: Eric Paris --- kernel/auditfilter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 4a11697cf5b8..4419d1fbcad1 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1085,7 +1085,8 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data, audit_free_rule(entry); break; default: - return -EINVAL; + err = -EINVAL; + WARN_ON(1); } return err; -- cgit v1.2.3 From e85322d21cfebeac64f58a204e9adc0bc5c1e46f Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Thu, 2 Oct 2014 22:05:19 -0400 Subject: audit: cull redundancy in audit_rule_change Re-factor audit_rule_change() to reduce the amount of code redundancy and simplify the logic. Signed-off-by: Richard Guy Briggs Signed-off-by: Eric Paris --- kernel/auditfilter.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 4419d1fbcad1..d214cd073a58 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1064,31 +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); 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); break; default: err = -EINVAL; WARN_ON(1); } + if (err || type == AUDIT_DEL_RULE) + audit_free_rule(entry); + return err; } -- cgit v1.2.3