diff options
author | Richard Guy Briggs <rgb@redhat.com> | 2017-08-23 07:03:39 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-11-10 16:08:56 -0500 |
commit | 42d5e37654e4cdb9fb2e2f3ab30045fee35c42d8 (patch) | |
tree | 5fa06c6189f135561616208016519bb61c309b1b /kernel/auditsc.c | |
parent | f7b53637c090bd8ce2dc74ad0f3aa1898aff2524 (diff) |
audit: filter PATH records keyed on filesystem magic
Tracefs or debugfs were causing hundreds to thousands of PATH records to
be associated with the init_module and finit_module SYSCALL records on a
few modules when the following rule was in place for startup:
-a always,exit -F arch=x86_64 -S init_module -F key=mod-load
Provide a method to ignore these large number of PATH records from
overwhelming the logs if they are not of interest. Introduce a new
filter list "AUDIT_FILTER_FS", with a new field type AUDIT_FSTYPE,
which keys off the filesystem 4-octet hexadecimal magic identifier to
filter specific filesystem PATH records.
An example rule would look like:
-a never,filesystem -F fstype=0x74726163 -F key=ignore_tracefs
-a never,filesystem -F fstype=0x64626720 -F key=ignore_debugfs
Arguably the better way to address this issue is to disable tracefs and
debugfs on boot from production systems.
See: https://github.com/linux-audit/audit-kernel/issues/16
See: https://github.com/linux-audit/audit-userspace/issues/8
Test case: https://github.com/linux-audit/audit-testsuite/issues/42
Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
[PM: fixed the whitespace damage in kernel/auditsc.c]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index aac1a41f82bd..c9bb29e17335 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -1869,10 +1869,33 @@ void __audit_inode_child(struct inode *parent, | |||
1869 | struct inode *inode = d_backing_inode(dentry); | 1869 | struct inode *inode = d_backing_inode(dentry); |
1870 | const char *dname = dentry->d_name.name; | 1870 | const char *dname = dentry->d_name.name; |
1871 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; | 1871 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; |
1872 | struct audit_entry *e; | ||
1873 | struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS]; | ||
1874 | int i; | ||
1872 | 1875 | ||
1873 | if (!context->in_syscall) | 1876 | if (!context->in_syscall) |
1874 | return; | 1877 | return; |
1875 | 1878 | ||
1879 | rcu_read_lock(); | ||
1880 | if (!list_empty(list)) { | ||
1881 | list_for_each_entry_rcu(e, list, list) { | ||
1882 | for (i = 0; i < e->rule.field_count; i++) { | ||
1883 | struct audit_field *f = &e->rule.fields[i]; | ||
1884 | |||
1885 | if (f->type == AUDIT_FSTYPE) { | ||
1886 | if (audit_comparator(parent->i_sb->s_magic, | ||
1887 | f->op, f->val)) { | ||
1888 | if (e->rule.action == AUDIT_NEVER) { | ||
1889 | rcu_read_unlock(); | ||
1890 | return; | ||
1891 | } | ||
1892 | } | ||
1893 | } | ||
1894 | } | ||
1895 | } | ||
1896 | } | ||
1897 | rcu_read_unlock(); | ||
1898 | |||
1876 | if (inode) | 1899 | if (inode) |
1877 | handle_one(inode); | 1900 | handle_one(inode); |
1878 | 1901 | ||