Skip to content

Commit

Permalink
audit: allow checking the type of audit message in the user filter
Browse files Browse the repository at this point in the history
When userspace sends messages to the audit system it includes a type.
We want to be able to filter messages based on that type without have to
do the all or nothing option currently available on the
AUDIT_FILTER_TYPE filter list.  Instead we should be able to use the
AUDIT_FILTER_USER filter list and just use the message type as one part
of the matching decision.

Signed-off-by: Eric Paris <eparis@redhat.com>
  • Loading branch information
Eric Paris committed Apr 16, 2013
1 parent 34c474d commit 62062cf
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
2 changes: 1 addition & 1 deletion include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid)
extern int audit_update_lsm_rules(void);

/* Private API (for audit.c only) */
extern int audit_filter_user(void);
extern int audit_filter_user(int type);
extern int audit_filter_type(int type);
extern int audit_receive_filter(int type, int pid, int seq,
void *data, size_t datasz, kuid_t loginuid,
Expand Down
2 changes: 1 addition & 1 deletion kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
return 0;

err = audit_filter_user();
err = audit_filter_user(msg_type);
if (err == 1) {
err = 0;
if (msg_type == AUDIT_USER_TTY) {
Expand Down
28 changes: 25 additions & 3 deletions kernel/auditfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,18 @@ static u32 audit_to_op(u32 op)
return n;
}

/* check if a field is valid for a given list */
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
{
switch(f->type) {
case AUDIT_MSGTYPE:
if (entry->rule.listnr != AUDIT_FILTER_TYPE &&
entry->rule.listnr != AUDIT_FILTER_USER)
return -EINVAL;
break;
};
return 0;
}

/* Translate struct audit_rule to kernel's rule respresentation.
* Exists for backward compatibility with userspace. */
Expand Down Expand Up @@ -459,6 +471,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
f->gid = INVALID_GID;
f->lsm_str = NULL;
f->lsm_rule = NULL;

err = audit_field_valid(entry, f);
if (err)
goto exit_free;

err = -EINVAL;

switch(f->type) {
case AUDIT_UID:
case AUDIT_EUID:
Expand Down Expand Up @@ -1354,7 +1373,7 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen)
return strncmp(p, dname, dlen);
}

static int audit_filter_user_rules(struct audit_krule *rule,
static int audit_filter_user_rules(struct audit_krule *rule, int type,
enum audit_state *state)
{
int i;
Expand All @@ -1378,6 +1397,9 @@ static int audit_filter_user_rules(struct audit_krule *rule,
result = audit_uid_comparator(audit_get_loginuid(current),
f->op, f->uid);
break;
case AUDIT_MSGTYPE:
result = audit_comparator(type, f->op, f->val);
break;
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
Expand All @@ -1404,15 +1426,15 @@ static int audit_filter_user_rules(struct audit_krule *rule,
return 1;
}

int audit_filter_user(void)
int audit_filter_user(int type)
{
enum audit_state state = AUDIT_DISABLED;
struct audit_entry *e;
int ret = 1;

rcu_read_lock();
list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
if (audit_filter_user_rules(&e->rule, &state)) {
if (audit_filter_user_rules(&e->rule, type, &state)) {
if (state == AUDIT_DISABLED)
ret = 0;
break;
Expand Down

0 comments on commit 62062cf

Please sign in to comment.