1
0
Fork 0

audit: re-structure audit field valid checks

Multiple checks were being done in one switch case statement that
started to cause some redundancies and awkward exceptions.  Separate the
valid field and op check from the select valid values checks.

Enforce the elimination of meaningless bitwise and greater/lessthan
checks on string fields and other fields with unrelated scalar values.

Please see the github issue
https://github.com/linux-audit/audit-kernel/issues/73

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
alistair/sunxi64-5.4-dsi
Richard Guy Briggs 2019-05-22 17:51:09 -04:00 committed by Paul Moore
parent b48345aafb
commit ecc68904a3
1 changed files with 34 additions and 22 deletions

View File

@ -335,7 +335,7 @@ static u32 audit_to_op(u32 op)
/* check if an audit field is valid */
static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
{
switch(f->type) {
switch (f->type) {
case AUDIT_MSGTYPE:
if (entry->rule.listnr != AUDIT_FILTER_EXCLUDE &&
entry->rule.listnr != AUDIT_FILTER_USER)
@ -347,7 +347,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
break;
}
switch(entry->rule.listnr) {
switch (entry->rule.listnr) {
case AUDIT_FILTER_FS:
switch(f->type) {
case AUDIT_FSTYPE:
@ -358,9 +358,16 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
}
}
switch(f->type) {
default:
return -EINVAL;
/* Check for valid field type and op */
switch (f->type) {
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
case AUDIT_ARG3:
case AUDIT_PERS: /* <uapi/linux/personality.h> */
case AUDIT_DEVMINOR:
/* all ops are valid */
break;
case AUDIT_UID:
case AUDIT_EUID:
case AUDIT_SUID:
@ -373,46 +380,52 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
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:
case AUDIT_INODE:
case AUDIT_SESSIONID:
case AUDIT_SUBJ_SEN:
case AUDIT_SUBJ_CLR:
case AUDIT_OBJ_LEV_LOW:
case AUDIT_OBJ_LEV_HIGH:
/* 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;
case AUDIT_LOGINUID_SET:
if ((f->val != 0) && (f->val != 1))
return -EINVAL;
/* FALL THROUGH */
case AUDIT_ARCH:
case AUDIT_FSTYPE:
case AUDIT_PERM:
case AUDIT_FILETYPE:
case AUDIT_FIELD_COMPARE:
case AUDIT_EXE:
/* only equal and not equal valid ops */
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
break;
default:
/* field not recognized */
return -EINVAL;
}
/* Check for select valid field values */
switch (f->type) {
case AUDIT_LOGINUID_SET:
if ((f->val != 0) && (f->val != 1))
return -EINVAL;
break;
case AUDIT_PERM:
if (f->val & ~15)
return -EINVAL;
@ -425,11 +438,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
if (f->val > AUDIT_MAX_FIELD_COMPARE)
return -EINVAL;
break;
case AUDIT_EXE:
if (f->op != Audit_not_equal && f->op != Audit_equal)
return -EINVAL;
default:
break;
}
return 0;
}