Samba and AuditD
by Alan Evangelista
I have installed audit 2.8.5 on a CentOS 7 and set up the following rule in
/etc/audit/rules.d/audit.rules:
-w /data
/data is shared via Samba to a Windows Server 2016 system. If I write to
/data in the CentOS7 system, I get the open syscall event in the auditd
log. If I write to the same directory in the Windows Server 2016, I see the
file in the /data directory in the CentOS7 system, but the event is not
logged by audit. Is that the expected behavior?
Thanks in advance.
3 years, 10 months
audit 3.0.1 released
by Steve Grubb
Hello,
I've just released a new version of the audit daemon. It can be
downloaded from http://people.redhat.com/sgrubb/audit. It will also be
in rawhide soon. The ChangeLog is:
- Update syscall table to the 5.11 kernel
- Add new --eoe-timeout option to ausearch and aureport (Burn Alting)
- Only enable periodic timers when listening on the network
- Upgrade libev to 4.33
- Add auparse_new_buffer function to auparse library
- Use the select libev backend unless aggregating events
- Add sudoers to some base audit rules
- Update the auparse normalizer for some new syscalls and event types
This release features 2 new experimental plugins. The statsd plugin should be
ready to try out. The other IDS plugin is more of a long term work in
progress. No timeline for it's development, either. (There is a known bug
where the ids plugin fails to build in some environments. There is a brand
new commit in github fixing this. Grab it if it fails to build.)
During the work for statsd, I found that the audit daemon is a little more
active than it should be. This was because it was enabling periodic timers
that are used to detect dead network connections when the daemon is configured
to be an aggregator. This is fixed and libev was updated to the latest
release. While I was in the libev section of code I did some testing betweek
using select and epoll as the event backend. Turns out select is about 4 ms
faster. So, as long as auditd is not receiving network events, it will use
select. If it does receive network events, then it will continue to use epoll
in case it needs a lot of descriptors.
Ausearch/report now have a new command line option to --eoe-timeout to help
gather event records into the right event if they were slow getting output.
Auditd also has a setting that could be considered the eoe_timeout default
setting. Libauparse automatically tries to read this if it has the
permissions.
SHA256: 994c4250d8fd43f3087a3c2ce73461832e30f1e9b278bf5bb03c3e07091155a5
Please let me know if you run across any problems with this release.
-Steve
3 years, 10 months
Auditd statsd integration
by Steve Grubb
Hello,
I have recently checked in to the audit tree 2 experimental plugins. You can
enable them by passing --enable-experimental to configure. One of the new
plugins is aimed at providing audit metrics to a statsd server. The idea
being that you can use this to relay the metrics to influxdb, prometheus or
some other collector. Then you can use Grafana to visualize and alert.
Currently, it supports the following metrics:
kernel.audit.lost
kernel.audit.backlog
auditd.free_space
auditd.plugin_current_depth
auditd.plugin_max_depth
audit_events.total_count
audit_events.total_failed
audit_events.avc_count
audit_events.fanotify_count
audit_events.logins_failed
audit_events.logins_success
audit_events.anomaly_count
audit_events.response_count
I'd be interested in hearing if this would be useful. And if these are the
right metrics that people are interested in. Should something else be
measured? Should an example Grafana dashboard be included?
Let me know what you think.
-Steve
3 years, 10 months
[PATCH 2/2] audit: show (grand)parents information of an audit context
by Daniel Walker
From: Phil Zhang <xuanyzha(a)cisco.com>
To ease the root cause analysis of SELinux AVCs, this new feature
traverses task structs to iteratively find all parent processes
starting with the denied process and ending at the kernel. Meanwhile,
it prints out the command lines and subject contexts of those parents.
This provides developers a clear view of how processes were spawned
and where transitions happened, without the need to reproduce the
issue and manually audit interesting events.
Example on bash over ssh:
$ runcon -u system_u -r system_r -t polaris_hm_t ls
...
type=PARENT msg=audit(1610548241.033:255): subj=root:unconfined_r:unconfined_t:s0-s0:c0.c1023 cmdline="-bash"
type=PARENT msg=audit(1610548241.033:255): subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 cmdline="sshd: root@pts/0"
type=PARENT msg=audit(1610548241.033:255): subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 cmdline="/tmp/sw/rp/0/0/rp_security/mount/usr/sbin/sshd
type=PARENT msg=audit(1610548241.033:255): subj=system_u:system_r:init_t:s0 cmdline="/init"
type=PARENT msg=audit(1610548241.033:255): subj=system_u:system_r:kernel_t:s0
...
Cc: xe-linux-external(a)cisco.com
Signed-off-by: Phil Zhang <xuanyzha(a)cisco.com>
Signed-off-by: Daniel Walker <danielwa(a)cisco.com>
---
include/uapi/linux/audit.h | 5 ++-
init/Kconfig | 7 +++++
kernel/audit.c | 3 +-
kernel/auditsc.c | 64 ++++++++++++++++++++++++++++++++++++++
4 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 7bea44b1c028..8f1a2880b198 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -119,6 +119,7 @@
#define AUDIT_BPF 1334 /* BPF subsystem */
#define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */
#define AUDIT_UBACKTRACE 1336 /* User land backtrace */
+#define AUDIT_PARENT 1340 /* Process Parent emit event */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -485,7 +486,9 @@ struct audit_features {
#define AUDIT_FEATURE_ONLY_UNSET_LOGINUID 0
#define AUDIT_FEATURE_LOGINUID_IMMUTABLE 1
#define AUDIT_FEATURE_UBACKTRACE_CONTEXT 2
-#define AUDIT_LAST_FEATURE AUDIT_FEATURE_UBACKTRACE_CONTEXT
+#define AUDIT_FEATURE_LIST_PARENTS 3
+#define AUDIT_LAST_FEATURE AUDIT_FEATURE_LIST_PARENTS
+
#define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
#define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31)) /* mask for __u32 */
diff --git a/init/Kconfig b/init/Kconfig
index 4327a8afb1f9..2dbc1c2aa833 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -446,6 +446,13 @@ config AUDIT_USER_BACKTRACE_SIZE
depends on AUDIT_USER_BACKTRACE
default 40
+config AUDIT_LIST_PARENTS
+ bool "Displaying parent processes in audit context messages"
+ def_bool n
+ depends on AUDITSYSCALL
+ help
+ Capture contexts and cmdlines of parent processes when auditing syscalls
+
source "kernel/irq/Kconfig"
source "kernel/time/Kconfig"
source "kernel/Kconfig.preempt"
diff --git a/kernel/audit.c b/kernel/audit.c
index 4608cddb4bb9..834adc462f47 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -165,10 +165,11 @@ static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
.features = 0,
.lock = 0,};
-static char *audit_feature_names[3] = {
+static char *audit_feature_names[4] = {
"only_unset_loginuid",
"loginuid_immutable",
"ubacktrace_context",
+ "list_parents",
};
/**
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d048b01345b8..c27e9f928bf1 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -96,6 +96,10 @@
/* number of audit rules */
int audit_n_rules;
+/* max length of per audit entry and max number of entries */
+#define MAX_PARENT_AUDIT_LEN 256
+#define MAX_PARENT_ENTRY_CNT 16
+
/* determines whether we collect data for signals sent */
int audit_signals;
@@ -1472,6 +1476,61 @@ static void audit_log_proctitle(void)
audit_log_end(ab);
}
+static void audit_log_parents(void)
+{
+ int res, len, item_cnt;
+ u32 sid;
+ char *buf;
+ char *ctx = NULL;
+ struct audit_context *context = audit_context();
+ struct audit_buffer *ab;
+ struct task_struct *task_iter;
+
+ if (!context || context->dummy)
+ return;
+
+ buf = kmalloc(MAX_PARENT_AUDIT_LEN, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ rcu_read_lock();
+ task_iter = rcu_dereference(current->real_parent);
+ for (item_cnt = 0; item_cnt < MAX_PARENT_ENTRY_CNT; ++item_cnt) {
+ ab = audit_log_start(context, GFP_ATOMIC, AUDIT_PARENT);
+ if (!ab)
+ break;
+
+ // get subject context
+ security_task_getsecid(task_iter, &sid);
+ if (sid) {
+ res = security_secid_to_secctx(sid, &ctx, &len);
+ if (!res) {
+ audit_log_format(ab, "subj=%-60s", ctx);
+ security_release_secctx(ctx, len);
+ }
+ }
+
+ // get cmdline
+ res = get_cmdline(task_iter, buf, MAX_PARENT_AUDIT_LEN);
+ if (res) {
+ res = audit_proctitle_rtrim(buf, res);
+ if (res) {
+ audit_log_format(ab, " proctitle=");
+ audit_log_n_untrustedstring(ab, buf, res);
+ }
+ }
+
+ audit_log_end(ab);
+
+ if (task_iter == task_iter->real_parent)
+ break;
+ task_iter = rcu_dereference(task_iter->real_parent);
+ }
+ rcu_read_unlock();
+
+ kfree(buf);
+}
+
#ifdef CONFIG_AUDIT_USER_BACKTRACE
static void audit_log_print_backtrace(struct audit_buffer *ab,
struct task_struct *tsk,
@@ -1682,6 +1741,11 @@ static void audit_log_exit(void)
audit_log_proctitle();
+#ifdef CONFIG_AUDIT_LIST_PARENTS
+ if (is_audit_feature_set(AUDIT_FEATURE_LIST_PARENTS))
+ audit_log_parents();
+#endif /* CONFIG_AUDIT_LIST_PARENTS */
+
#ifdef CONFIG_AUDIT_USER_BACKTRACE
if (is_audit_feature_set(AUDIT_FEATURE_UBACKTRACE_CONTEXT))
audit_log_ubacktrace(current, context);
--
2.17.1
3 years, 10 months
[PATCH 1/2] audit: show user land backtrace as part of audit context messages
by Daniel Walker
From: Victor Kamensky <kamensky(a)cisco.com>
To efficiently find out where SELinux AVC denial is comming from
take backtrace of user land process and display it as type=UBACKTRACE
message that comes as audit context for SELinux AVC and other audit
messages.
By default UBACKTRACE context messages are off. Needs to be enabled
through audit AUDIT_FEATURE_UBACKTRACE_CONTEXT feature.
Context UBACKTRACE message example:
type=UBACKTRACE msg=audit(1574205625.557:30): backtrace=libc-2.30.so+0xc99ab:dmesg.util-linux+0x1483:libc-2.30.so+0x1e35:dmesg.util-linux+0x1e5a
I.e because of ASLR instead of absolute user land addresses, name
of executable or library captured and followed by offset from text
segment vma. To decode backtrace entry: find executable or library
symbol file, find its text segment vma and add offset to it; run
'addr2line -f -e symbol_file resulting_address'.
Note feature depends on PERF_EVENTS, from perf subsystem it uses
perf_callchain_user function on architectures where it is implemented.
And it has the same capturing restriction as 'perf -g': user land code
must be compiled with -fno-omit-frame-pointer option, otherwise kernel
is not capable walk user land stack frames.
Cc: xe-linux-external(a)cisco.com
Signed-off-by: Victor Kamensky <kamensky(a)cisco.com>
Signed-off-by: Ruslan Bilovol <rbilovol(a)cisco.com>
Signed-off-by: Daniel Walker <danielwa(a)cisco.com>
---
include/uapi/linux/audit.h | 6 ++-
init/Kconfig | 13 ++++++
kernel/audit.c | 3 +-
kernel/auditsc.c | 93 ++++++++++++++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index cd2d8279a5e4..7bea44b1c028 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -118,6 +118,7 @@
#define AUDIT_TIME_ADJNTPVAL 1333 /* NTP value adjustment */
#define AUDIT_BPF 1334 /* BPF subsystem */
#define AUDIT_EVENT_LISTENER 1335 /* Task joined multicast read socket */
+#define AUDIT_UBACKTRACE 1336 /* User land backtrace */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -474,7 +475,7 @@ struct audit_status {
};
struct audit_features {
-#define AUDIT_FEATURE_VERSION 1
+#define AUDIT_FEATURE_VERSION 2
__u32 vers;
__u32 mask; /* which bits we are dealing with */
__u32 features; /* which feature to enable/disable */
@@ -483,7 +484,8 @@ struct audit_features {
#define AUDIT_FEATURE_ONLY_UNSET_LOGINUID 0
#define AUDIT_FEATURE_LOGINUID_IMMUTABLE 1
-#define AUDIT_LAST_FEATURE AUDIT_FEATURE_LOGINUID_IMMUTABLE
+#define AUDIT_FEATURE_UBACKTRACE_CONTEXT 2
+#define AUDIT_LAST_FEATURE AUDIT_FEATURE_UBACKTRACE_CONTEXT
#define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE)
#define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31)) /* mask for __u32 */
diff --git a/init/Kconfig b/init/Kconfig
index b77c60f8b963..4327a8afb1f9 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -433,6 +433,19 @@ config AUDITSYSCALL
depends on AUDIT && HAVE_ARCH_AUDITSYSCALL
select FSNOTIFY
+config AUDIT_USER_BACKTRACE
+ bool "Enable user land backtrace in audit context messages"
+ def_bool n
+ depends on AUDITSYSCALL && PERF_EVENTS
+ help
+ Enable UBACKTRACE audit context messages, capturing backtrace of
+ user land process causing the message.
+
+config AUDIT_USER_BACKTRACE_SIZE
+ int "Maximum size of user land backtrace entries captured in UBACKTACE"
+ depends on AUDIT_USER_BACKTRACE
+ default 40
+
source "kernel/irq/Kconfig"
source "kernel/time/Kconfig"
source "kernel/Kconfig.preempt"
diff --git a/kernel/audit.c b/kernel/audit.c
index 1ffc2e059027..4608cddb4bb9 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -165,9 +165,10 @@ static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION,
.features = 0,
.lock = 0,};
-static char *audit_feature_names[2] = {
+static char *audit_feature_names[3] = {
"only_unset_loginuid",
"loginuid_immutable",
+ "ubacktrace_context",
};
/**
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index ce8c9e2279ba..d048b01345b8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -67,6 +67,7 @@
#include <linux/highmem.h>
#include <linux/syscalls.h>
#include <asm/syscall.h>
+#include <linux/mmap_lock.h>
#include <linux/capability.h>
#include <linux/fs_struct.h>
#include <linux/compat.h>
@@ -74,6 +75,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/fsnotify_backend.h>
+#include <linux/perf_event.h>
#include <uapi/linux/limits.h>
#include <uapi/linux/netfilter/nf_tables.h>
@@ -1470,6 +1472,92 @@ static void audit_log_proctitle(void)
audit_log_end(ab);
}
+#ifdef CONFIG_AUDIT_USER_BACKTRACE
+static void audit_log_print_backtrace(struct audit_buffer *ab,
+ struct task_struct *tsk,
+ struct perf_callchain_entry *entry)
+{
+ struct mm_struct *mm;
+ const struct vm_area_struct *vma;
+ struct file *file;
+ const char *filename;
+ unsigned long vmstart;
+ int i;
+
+ audit_log_format(ab, "backtrace=");
+
+ mm = tsk->mm;
+ mmap_write_lock(mm);
+ for (i = 0; i < entry->nr; i++) {
+ vma = find_vma(mm, entry->ip[i]);
+ if (vma && (vma->vm_flags & VM_EXEC)) {
+ file = vma->vm_file;
+ vmstart = vma->vm_start;
+
+ if (file && file->f_path.dentry) {
+ filename = file->f_path.dentry->d_name.name;
+ } else {
+ filename = "";
+ }
+
+ if (i == 0) {
+ audit_log_format(ab, "%s+0x%llx",
+ filename,
+ entry->ip[i] - vmstart);
+ } else {
+ audit_log_format(ab, ":%s+0x%llx",
+ filename,
+ entry->ip[i] - vmstart);
+ }
+ } else {
+ /* No corresponding executable vma, assume garbage entry */
+ break;
+ }
+ }
+ mmap_write_unlock(mm);
+}
+
+static void audit_log_ubacktrace(struct task_struct *tsk,
+ struct audit_context *context)
+{
+ struct audit_buffer *ab;
+ struct perf_callchain_entry_ctx ctx;
+ struct pt_regs *regs = NULL;
+
+ if (tsk->mm)
+ regs = task_pt_regs(tsk);
+
+ if (regs) {
+ ctx.entry = kmalloc(sizeof(struct perf_callchain_entry) +
+ CONFIG_AUDIT_USER_BACKTRACE_SIZE * sizeof(__u64),
+ GFP_KERNEL);
+ if (ctx.entry) {
+ mm_segment_t fs;
+
+ ctx.max_stack = CONFIG_AUDIT_USER_BACKTRACE_SIZE;
+ ctx.nr = ctx.entry->nr = 0;
+ ctx.contexts = 0;
+ ctx.contexts_maxed = false;
+
+ fs = force_uaccess_begin();
+ perf_callchain_user(&ctx, regs);
+ force_uaccess_end(fs);
+
+ if (ctx.entry->nr) {
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_UBACKTRACE);
+
+ if (ab) {
+ audit_log_print_backtrace(ab, tsk, ctx.entry);
+ audit_log_end(ab);
+ }
+ }
+
+ kfree(ctx.entry);
+ }
+ }
+}
+#endif /* CONFIG_AUDIT_USER_BACKTRACE */
+
static void audit_log_exit(void)
{
int i, call_panic = 0;
@@ -1594,6 +1682,11 @@ static void audit_log_exit(void)
audit_log_proctitle();
+#ifdef CONFIG_AUDIT_USER_BACKTRACE
+ if (is_audit_feature_set(AUDIT_FEATURE_UBACKTRACE_CONTEXT))
+ audit_log_ubacktrace(current, context);
+#endif /* CONFIG_AUDIT_USER_BACKTRACE */
+
/* Send end of event record to help user space know we are finished */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
if (ab)
--
2.17.1
3 years, 10 months