From ecc68904a3e5efb07cb4f0b97d15c7e0e4623d13 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 22 May 2019 17:51:09 -0400 Subject: 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 Signed-off-by: Paul Moore --- kernel/auditfilter.c | 56 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 303fb04770ce..d5e54e944f72 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -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: /* */ + 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; } -- cgit From bf361231c295d92a28ca283ea713f56e93e55796 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Thu, 9 May 2019 20:01:36 -0400 Subject: audit: add saddr_fam filter field Provide a method to filter out sockaddr and bind calls by network address family. Existing SOCKADDR records are listed for any network activity. Implement the AUDIT_SADDR_FAM field selector to be able to classify or limit records to specific network address families, such as AF_INET or AF_INET6. An example of a network record that is unlikely to be useful and flood the logs: type=SOCKADDR msg=audit(07/27/2017 12:18:27.019:845) : saddr={ fam=local path=/var/run/nscd/socket } type=SYSCALL msg=audit(07/27/2017 12:18:27.019:845) : arch=x86_64 syscall=connect success=no exit=ENOENT(No such file or directory) a0=0x3 a1=0x7fff229c4980 a2=0x6e a3=0x6 items=1 ppid=3301 pid=6145 auid=sgrubb uid=sgrubb gid=sgrubb euid=sgrubb suid=sgrubb fsuid=sgrubb egid=sgrubb sgid=sgrubb fsgid=sgrubb tty=pts3 ses=4 comm=bash exe=/usr/bin/bash subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=network-test Please see the audit-testsuite PR at https://github.com/linux-audit/audit-testsuite/pull/87 Please see the github issue https://github.com/linux-audit/audit-kernel/issues/64 Please see the github issue for the accompanying userspace support https://github.com/linux-audit/audit-userspace/issues/93 Signed-off-by: Richard Guy Briggs [PM: merge fuzz in auditfilter.c] Signed-off-by: Paul Moore --- kernel/auditfilter.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index d5e54e944f72..e69d136eeaf6 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -391,6 +391,7 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) case AUDIT_SUBJ_CLR: case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: + case AUDIT_SADDR_FAM: /* bit ops are only useful on syscall args */ if (f->op == Audit_bitmask || f->op == Audit_bittest) return -EINVAL; @@ -438,6 +439,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_SADDR_FAM: + if (f->val >= AF_MAX) + return -EINVAL; + break; default: break; } -- cgit From 839d05e413856bd686a33b59294d4e8238169320 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 30 May 2019 12:53:42 -0400 Subject: audit: remove the BUG() calls in the audit rule comparison functions The audit_data_to_entry() function ensures that the operator is valid so we can get rid of these BUG() calls. We keep the "return 0" just so the system behaves in a sane-ish manner should something go horribly wrong. Signed-off-by: Paul Moore Acked-by: Richard Guy Briggs --- kernel/auditfilter.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'kernel/auditfilter.c') diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index e69d136eeaf6..1a21b6aa50d1 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1220,7 +1220,6 @@ int audit_comparator(u32 left, u32 op, u32 right) case Audit_bittest: return ((left & right) == right); default: - BUG(); return 0; } } @@ -1243,7 +1242,6 @@ int audit_uid_comparator(kuid_t left, u32 op, kuid_t right) case Audit_bitmask: case Audit_bittest: default: - BUG(); return 0; } } @@ -1266,7 +1264,6 @@ int audit_gid_comparator(kgid_t left, u32 op, kgid_t right) case Audit_bitmask: case Audit_bittest: default: - BUG(); return 0; } } -- cgit