Commit ab61d38e authored by Eric Paris's avatar Eric Paris

audit: make validity checking generic

We have 2 interfaces to send audit rules.  Rather than check validity of
things in 2 places make a helper function.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent 62062cf8
...@@ -310,7 +310,7 @@ static u32 audit_to_op(u32 op) ...@@ -310,7 +310,7 @@ static u32 audit_to_op(u32 op)
return n; return n;
} }
/* check if a field is valid for a given list */ /* check if an audit field is valid */
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
{ {
switch(f->type) { switch(f->type) {
...@@ -320,6 +320,69 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) ...@@ -320,6 +320,69 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
return -EINVAL; return -EINVAL;
break; break;
}; };
switch(f->type) {
default:
return -EINVAL;
case AUDIT_UID:
case AUDIT_EUID:
case AUDIT_SUID:
case AUDIT_FSUID:
case AUDIT_LOGINUID:
case AUDIT_OBJ_UID:
case AUDIT_GID:
case AUDIT_EGID:
case AUDIT_SGID:
case AUDIT_FSGID:
case AUDIT_OBJ_GID:
case AUDIT_PID:
case AUDIT_PERS:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
/* bit ops are only useful on syscall args */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
return -EINVAL;
break;
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
case AUDIT_ARG3:
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:
case AUDIT_WATCH:
case AUDIT_DIR:
case AUDIT_FILTERKEY:
break;
/* arch is only allowed to be = or != */
case AUDIT_ARCH:
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
break;
case AUDIT_PERM:
if (f->val & ~15)
return -EINVAL;
break;
case AUDIT_FILETYPE:
if (f->val & ~S_IFMT)
return -EINVAL;
break;
case AUDIT_FIELD_COMPARE:
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
};
return 0; return 0;
} }
...@@ -361,18 +424,17 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) ...@@ -361,18 +424,17 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
if (f->op == Audit_bad) if (f->op == Audit_bad)
goto exit_free; goto exit_free;
switch(f->type) { err = audit_field_valid(entry, f);
default: if (err)
goto exit_free; goto exit_free;
err = -EINVAL;
switch (f->type) {
case AUDIT_UID: case AUDIT_UID:
case AUDIT_EUID: case AUDIT_EUID:
case AUDIT_SUID: case AUDIT_SUID:
case AUDIT_FSUID: case AUDIT_FSUID:
case AUDIT_LOGINUID: case AUDIT_LOGINUID:
/* bit ops not implemented for uid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
f->uid = make_kuid(current_user_ns(), f->val); f->uid = make_kuid(current_user_ns(), f->val);
if (!uid_valid(f->uid)) if (!uid_valid(f->uid))
goto exit_free; goto exit_free;
...@@ -381,45 +443,13 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) ...@@ -381,45 +443,13 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
case AUDIT_EGID: case AUDIT_EGID:
case AUDIT_SGID: case AUDIT_SGID:
case AUDIT_FSGID: case AUDIT_FSGID:
/* bit ops not implemented for gid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
f->gid = make_kgid(current_user_ns(), f->val); f->gid = make_kgid(current_user_ns(), f->val);
if (!gid_valid(f->gid)) if (!gid_valid(f->gid))
goto exit_free; goto exit_free;
break; break;
case AUDIT_PID:
case AUDIT_PERS:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
/* bit ops are only useful on syscall args */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
break;
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
case AUDIT_ARG3:
break;
/* arch is only allowed to be = or != */
case AUDIT_ARCH: case AUDIT_ARCH:
if (f->op != Audit_not_equal && f->op != Audit_equal)
goto exit_free;
entry->rule.arch_f = f; entry->rule.arch_f = f;
break; break;
case AUDIT_PERM:
if (f->val & ~15)
goto exit_free;
break;
case AUDIT_FILETYPE:
if (f->val & ~S_IFMT)
goto exit_free;
break;
case AUDIT_INODE: case AUDIT_INODE:
err = audit_to_inode(&entry->rule, f); err = audit_to_inode(&entry->rule, f);
if (err) if (err)
...@@ -477,18 +507,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, ...@@ -477,18 +507,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
goto exit_free; goto exit_free;
err = -EINVAL; err = -EINVAL;
switch (f->type) {
switch(f->type) {
case AUDIT_UID: case AUDIT_UID:
case AUDIT_EUID: case AUDIT_EUID:
case AUDIT_SUID: case AUDIT_SUID:
case AUDIT_FSUID: case AUDIT_FSUID:
case AUDIT_LOGINUID: case AUDIT_LOGINUID:
case AUDIT_OBJ_UID: case AUDIT_OBJ_UID:
/* bit ops not implemented for uid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
f->uid = make_kuid(current_user_ns(), f->val); f->uid = make_kuid(current_user_ns(), f->val);
if (!uid_valid(f->uid)) if (!uid_valid(f->uid))
goto exit_free; goto exit_free;
...@@ -498,27 +523,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, ...@@ -498,27 +523,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
case AUDIT_SGID: case AUDIT_SGID:
case AUDIT_FSGID: case AUDIT_FSGID:
case AUDIT_OBJ_GID: case AUDIT_OBJ_GID:
/* bit ops not implemented for gid comparisons */
if (f->op == Audit_bitmask || f->op == Audit_bittest)
goto exit_free;
f->gid = make_kgid(current_user_ns(), f->val); f->gid = make_kgid(current_user_ns(), f->val);
if (!gid_valid(f->gid)) if (!gid_valid(f->gid))
goto exit_free; goto exit_free;
break; break;
case AUDIT_PID:
case AUDIT_PERS:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
case AUDIT_ARG3:
break;
case AUDIT_ARCH: case AUDIT_ARCH:
entry->rule.arch_f = f; entry->rule.arch_f = f;
break; break;
...@@ -589,20 +597,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, ...@@ -589,20 +597,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
entry->rule.buflen += f->val; entry->rule.buflen += f->val;
entry->rule.filterkey = str; entry->rule.filterkey = str;
break; break;
case AUDIT_PERM:
if (f->val & ~15)
goto exit_free;
break;
case AUDIT_FILETYPE:
if (f->val & ~S_IFMT)
goto exit_free;
break;
case AUDIT_FIELD_COMPARE:
if (f->val > AUDIT_MAX_FIELD_COMPARE)
goto exit_free;
break;
default:
goto exit_free;
} }
} }
......
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