Auditing device files
by Pavithra P
Hi,
I am trying to see what commands are typed in my terminal and serial
port. For that I am using auditd daemon which helps me in auditing
files.
I thought of a creating audit rules on /dev/tty and /dev/ttyAMA0 for
seeing whats happening on terminal and serial device respectively
auditctl -w /dev/tty -p rwx -k terminal
auditctl -w /dev/ttyAMA0 -p rwx -k serialport
But this records only the echo on tty. I cant audit all the commands
typed on the terminal. I enabled tty logging in the PAM file too by
adding session required pam_tty_audit.so enable=* in /etc/pam.d/sshd
file.
Is there any other way to do this auditing. I want to use auditd
daemon only so that all my auditing log is in one file.
--
With regards,
P Pavithra
8 years, 3 months
[PATCH] audit: fix a double fetch in audit_log_single_execve_arg()
by Paul Moore
From: Paul Moore <paul(a)paul-moore.com>
There is a double fetch problem in audit_log_single_execve_arg()
where we first check the execve(2) argumnets for any "bad" characters
which would require hex encoding and then re-fetch the arguments for
logging in the audit record[1]. Of course this leaves a window of
opportunity for an unsavory application to munge with the data.
This patch reworks things by only fetching the argument data once[2]
into a buffer where it is scanned and logged into the audit
records(s). In addition to fixing the double fetch, this patch
improves on the original code in a few other ways: better handling
of large arguments which require encoding, stricter record length
checking, and some performance improvements (completely unverified,
but we got rid of some strlen() calls, that's got to be a good
thing).
As part of the development of this patch, I've also created a basic
regression test for the audit-testsuite, the test can be tracked on
GitHub at the following link:
* https://github.com/linux-audit/audit-testsuite/issues/25
[1] If you pay careful attention, there is actually a triple fetch
problem due to a strnlen_user() call at the top of the function.
[2] This is a tiny white lie, we do make a call to strnlen_user()
prior to fetching the argument data. I don't like it, but due to the
way the audit record is structured we really have no choice unless we
copy the entire argument at once (which would require a rather
wasteful allocation). The good news is that with this patch the
kernel no longer relies on this strnlen_user() value for anything
beyond recording it in the log, we also update it with a trustworthy
value whenever possible.
Reported-by: Pengfei Wang <wpengfeinudt(a)gmail.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Paul Moore <paul(a)paul-moore.com>
---
kernel/auditsc.c | 332 +++++++++++++++++++++++++++---------------------------
1 file changed, 164 insertions(+), 168 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index aa3feec..c65af21 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -73,6 +73,7 @@
#include <linux/compat.h>
#include <linux/ctype.h>
#include <linux/string.h>
+#include <linux/uaccess.h>
#include <uapi/linux/limits.h>
#include "audit.h"
@@ -82,7 +83,8 @@
#define AUDITSC_SUCCESS 1
#define AUDITSC_FAILURE 2
-/* no execve audit message should be longer than this (userspace limits) */
+/* no execve audit message should be longer than this (userspace limits),
+ * see the note near the top of audit_log_execve_info() about this value */
#define MAX_EXECVE_AUDIT_LEN 7500
/* max length to print of cmdline/proctitle value during audit */
@@ -992,184 +994,178 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
return rc;
}
-/*
- * to_send and len_sent accounting are very loose estimates. We aren't
- * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being
- * within about 500 bytes (next page boundary)
- *
- * why snprintf? an int is up to 12 digits long. if we just assumed when
- * logging that a[%d]= was going to be 16 characters long we would be wasting
- * space in every audit message. In one 7500 byte message we can log up to
- * about 1000 min size arguments. That comes down to about 50% waste of space
- * if we didn't do the snprintf to find out how long arg_num_len was.
- */
-static int audit_log_single_execve_arg(struct audit_context *context,
- struct audit_buffer **ab,
- int arg_num,
- size_t *len_sent,
- const char __user *p,
- char *buf)
+static void audit_log_execve_info(struct audit_context *context,
+ struct audit_buffer **ab)
{
- char arg_num_len_buf[12];
- const char __user *tmp_p = p;
- /* how many digits are in arg_num? 5 is the length of ' a=""' */
- size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5;
- size_t len, len_left, to_send;
- size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
- unsigned int i, has_cntl = 0, too_long = 0;
- int ret;
-
- /* strnlen_user includes the null we don't want to send */
- len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1;
-
- /*
- * We just created this mm, if we can't find the strings
- * we just copied into it something is _very_ wrong. Similar
- * for strings that are too long, we should not have created
- * any.
- */
- if (WARN_ON_ONCE(len < 0 || len > MAX_ARG_STRLEN - 1)) {
- send_sig(SIGKILL, current, 0);
- return -1;
+ long len_max;
+ long len_rem;
+ long len_full;
+ long len_buf;
+ long len_abuf;
+ long len_tmp;
+ bool require_data;
+ bool encode;
+ unsigned int iter;
+ unsigned int arg;
+ char *buf_head;
+ char *buf;
+ const char __user *p = (const char __user *)current->mm->arg_start;
+
+ /* NOTE: this buffer needs to be large enough to hold all the non-arg
+ * data we put in the audit record for this argument (see the
+ * code below) ... at this point in time 96 is plenty */
+ char abuf[96];
+
+ /* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the
+ * current value of 7500 is not as important as the fact that it
+ * is less than 8k, a setting of 7500 gives us plenty of wiggle
+ * room if we go over a little bit in the logging below */
+ WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500);
+ len_max = MAX_EXECVE_AUDIT_LEN;
+
+ /* scratch buffer to hold the userspace args */
+ buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
+ if (!buf_head) {
+ audit_panic("out of memory for argv string");
+ return;
}
+ buf = buf_head;
- /* walk the whole argument looking for non-ascii chars */
+ audit_log_format(*ab, "argc=%d", context->execve.argc);
+
+ len_rem = len_max;
+ len_buf = 0;
+ len_full = 0;
+ require_data = true;
+ encode = false;
+ iter = 0;
+ arg = 0;
do {
- if (len_left > MAX_EXECVE_AUDIT_LEN)
- to_send = MAX_EXECVE_AUDIT_LEN;
- else
- to_send = len_left;
- ret = copy_from_user(buf, tmp_p, to_send);
- /*
- * There is no reason for this copy to be short. We just
- * copied them here, and the mm hasn't been exposed to user-
- * space yet.
- */
- if (ret) {
- WARN_ON(1);
- send_sig(SIGKILL, current, 0);
- return -1;
- }
- buf[to_send] = '\0';
- has_cntl = audit_string_contains_control(buf, to_send);
- if (has_cntl) {
- /*
- * hex messages get logged as 2 bytes, so we can only
- * send half as much in each message
- */
- max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2;
- break;
- }
- len_left -= to_send;
- tmp_p += to_send;
- } while (len_left > 0);
-
- len_left = len;
-
- if (len > max_execve_audit_len)
- too_long = 1;
-
- /* rewalk the argument actually logging the message */
- for (i = 0; len_left > 0; i++) {
- int room_left;
-
- if (len_left > max_execve_audit_len)
- to_send = max_execve_audit_len;
- else
- to_send = len_left;
-
- /* do we have space left to send this argument in this ab? */
- room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent;
- if (has_cntl)
- room_left -= (to_send * 2);
- else
- room_left -= to_send;
- if (room_left < 0) {
- *len_sent = 0;
- audit_log_end(*ab);
- *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE);
- if (!*ab)
- return 0;
- }
+ /* NOTE: we don't ever want to trust this value for anything
+ * serious, but the audit record format insists we
+ * provide an argument length for really long arguments,
+ * e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but
+ * to use strncpy_from_user() to obtain this value for
+ * recording in the log, although we don't use it
+ * anywhere here to avoid a double-fetch problem */
+ if (len_full == 0)
+ len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1;
+
+ /* read more data from userspace */
+ if (require_data) {
+ /* can we make more room in the buffer? */
+ if (buf != buf_head) {
+ memmove(buf_head, buf, len_buf);
+ buf = buf_head;
+ }
+
+ /* fetch as much as we can of the argument */
+ len_tmp = strncpy_from_user(&buf_head[len_buf], p,
+ len_max - len_buf);
+ if (len_tmp == -EFAULT) {
+ /* unable to copy from userspace */
+ send_sig(SIGKILL, current, 0);
+ goto out;
+ } else if (len_tmp == (len_max - len_buf)) {
+ /* buffer is not large enough */
+ require_data = true;
+ /* NOTE: if we are going to span multiple
+ * buffers force the encoding so we stand
+ * a chance at a sane len_full value and
+ * consistent record encoding */
+ encode = true;
+ len_full = len_full * 2;
+ p += len_tmp;
+ } else {
+ require_data = false;
+ if (!encode)
+ encode = audit_string_contains_control(
+ buf, len_tmp);
+ /* try to use a trusted value for len_full */
+ if (len_full < len_max)
+ len_full = (encode ?
+ len_tmp * 2 : len_tmp);
+ p += len_tmp + 1;
+ }
+ len_buf += len_tmp;
+ buf_head[len_buf] = '\0';
- /*
- * first record needs to say how long the original string was
- * so we can be sure nothing was lost.
- */
- if ((i == 0) && (too_long))
- audit_log_format(*ab, " a%d_len=%zu", arg_num,
- has_cntl ? 2*len : len);
-
- /*
- * normally arguments are small enough to fit and we already
- * filled buf above when we checked for control characters
- * so don't bother with another copy_from_user
- */
- if (len >= max_execve_audit_len)
- ret = copy_from_user(buf, p, to_send);
- else
- ret = 0;
- if (ret) {
- WARN_ON(1);
- send_sig(SIGKILL, current, 0);
- return -1;
+ /* length of the buffer in the audit record? */
+ len_abuf = (encode ? len_buf * 2 : len_buf + 2);
}
- buf[to_send] = '\0';
-
- /* actually log it */
- audit_log_format(*ab, " a%d", arg_num);
- if (too_long)
- audit_log_format(*ab, "[%d]", i);
- audit_log_format(*ab, "=");
- if (has_cntl)
- audit_log_n_hex(*ab, buf, to_send);
- else
- audit_log_string(*ab, buf);
-
- p += to_send;
- len_left -= to_send;
- *len_sent += arg_num_len;
- if (has_cntl)
- *len_sent += to_send * 2;
- else
- *len_sent += to_send;
- }
- /* include the null we didn't log */
- return len + 1;
-}
-static void audit_log_execve_info(struct audit_context *context,
- struct audit_buffer **ab)
-{
- int i, len;
- size_t len_sent = 0;
- const char __user *p;
- char *buf;
+ /* write as much as we can to the audit log */
+ if (len_buf > 0) {
+ /* NOTE: some magic numbers here - basically if we
+ * can't fit a reasonable amount of data into the
+ * existing audit buffer, flush it and start with
+ * a new buffer */
+ if ((sizeof(abuf) + 8) > len_rem) {
+ len_rem = len_max;
+ audit_log_end(*ab);
+ *ab = audit_log_start(context,
+ GFP_KERNEL, AUDIT_EXECVE);
+ if (!*ab)
+ goto out;
+ }
- p = (const char __user *)current->mm->arg_start;
+ /* create the non-arg portion of the arg record */
+ len_tmp = 0;
+ if (require_data || (iter > 0) ||
+ ((len_abuf + sizeof(abuf)) > len_rem)) {
+ if (iter == 0) {
+ len_tmp += snprintf(&abuf[len_tmp],
+ sizeof(abuf) - len_tmp,
+ " a%d_len=%lu",
+ arg, len_full);
+ }
+ len_tmp += snprintf(&abuf[len_tmp],
+ sizeof(abuf) - len_tmp,
+ " a%d[%d]=", arg, iter++);
+ } else
+ len_tmp += snprintf(&abuf[len_tmp],
+ sizeof(abuf) - len_tmp,
+ " a%d=", arg);
+ WARN_ON(len_tmp >= sizeof(abuf));
+ abuf[sizeof(abuf) - 1] = '\0';
+
+ /* log the arg in the audit record */
+ audit_log_format(*ab, "%s", abuf);
+ len_rem -= len_tmp;
+ len_tmp = len_buf;
+ if (encode) {
+ if (len_abuf > len_rem)
+ len_tmp = len_rem / 2; /* encoding */
+ audit_log_n_hex(*ab, buf, len_tmp);
+ len_rem -= len_tmp * 2;
+ len_abuf -= len_tmp * 2;
+ } else {
+ if (len_abuf > len_rem)
+ len_tmp = len_rem - 2; /* quotes */
+ audit_log_n_string(*ab, buf, len_tmp);
+ len_rem -= len_tmp + 2;
+ /* don't subtract the "2" because we still need
+ * to add quotes to the remaining string */
+ len_abuf -= len_tmp;
+ }
+ len_buf -= len_tmp;
+ buf += len_tmp;
+ }
- audit_log_format(*ab, "argc=%d", context->execve.argc);
+ /* ready to move to the next argument? */
+ if ((len_buf == 0) && !require_data) {
+ arg++;
+ iter = 0;
+ len_full = 0;
+ require_data = true;
+ encode = false;
+ }
+ } while (arg < context->execve.argc);
- /*
- * we need some kernel buffer to hold the userspace args. Just
- * allocate one big one rather than allocating one of the right size
- * for every single argument inside audit_log_single_execve_arg()
- * should be <8k allocation so should be pretty safe.
- */
- buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL);
- if (!buf) {
- audit_panic("out of memory for argv string");
- return;
- }
+ /* NOTE: the caller handles the final audit_log_end() call */
- for (i = 0; i < context->execve.argc; i++) {
- len = audit_log_single_execve_arg(context, ab, i,
- &len_sent, p, buf);
- if (len <= 0)
- break;
- p += len;
- }
- kfree(buf);
+out:
+ kfree(buf_head);
}
static void show_special(struct audit_context *context, int *call_panic)
8 years, 3 months
[PATCH] Add .gitignore file for git-svn and github.
by Richard Guy Briggs
Ignore generated files if using git.
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
trunk/.gitignore | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 54 insertions(+), 0 deletions(-)
create mode 100644 trunk/.gitignore
diff --git a/trunk/.gitignore b/trunk/.gitignore
new file mode 100644
index 0000000..a328f80
--- /dev/null
+++ b/trunk/.gitignore
@@ -0,0 +1,54 @@
+*~
+*.[oa]
+*.lo
+*.la
+*.pc
+gen_*_h
+INSTALL
+Makefile
+Makefile.in
+TAGS
+/aclocal.m4
+/autom4te.cache
+/audit*.tar.gz
+/audit-rhel?.spec
+/config.guess
+/config.sub
+/config.status
+/config.log
+/config.h
+/config.h.in
+/configure
+/compile
+/depcomp
+/install-sh
+/libtool
+/missing
+/py-compile
+.libs/
+.deps/
+audisp/audispd
+audisp/plugins/remote/audisp-remote
+audisp/plugins/zos-remote/audispd-zos-remote
+auparse/*tabs.h
+auparse/epoll_ctls.h
+auparse/strsplit.c
+bindings/swig/python/audit.py
+bindings/swig/python/audit_wrap.c
+bindings/swig/python3/audit.py
+bindings/swig/python3/audit_wrap.c
+lib/*tabs.h
+lib/*tables.h
+m4/libtool.m4
+m4/lt*.m4
+src/auditctl
+src/auditd
+src/aureport
+src/ausearch
+src/autrace
+stamp-h1
+test-driver
+tools/aulast/aulast
+tools/aulastlog/aulastlog
+tools/ausyscall/ausyscall
+tools/auvirt/auvirt
--
1.7.1
8 years, 3 months
[audit-testsuite PATCH] exec_execve: add some simple tests for the EXECVE record
by Paul Moore
Beyond the simple existence of the EXECVE record, we test three basic
things:
* large number of arguments spanning multiple records
* single large argument spanning multiple records
* single argument that requires hex encoding
Signed-off-by: Paul Moore <paul(a)paul-moore.com>
---
tests/Makefile | 1
tests/exec_execve/.gitignore | 1
tests/exec_execve/Makefile | 11 +++
tests/exec_execve/execve_arg_gen.c | 108 +++++++++++++++++++++++++++++++
tests/exec_execve/test | 124 ++++++++++++++++++++++++++++++++++++
5 files changed, 245 insertions(+)
create mode 100644 tests/exec_execve/.gitignore
create mode 100644 tests/exec_execve/Makefile
create mode 100644 tests/exec_execve/execve_arg_gen.c
create mode 100755 tests/exec_execve/test
diff --git a/tests/Makefile b/tests/Makefile
index decb6b2..48a8307 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -5,6 +5,7 @@ DISTRO = $(shell ./os_detect)
SUBDIRS := \
exec_name \
+ exec_execve \
file_create \
file_delete \
file_rename \
diff --git a/tests/exec_execve/.gitignore b/tests/exec_execve/.gitignore
new file mode 100644
index 0000000..fb9f5a6
--- /dev/null
+++ b/tests/exec_execve/.gitignore
@@ -0,0 +1 @@
+execve_arg_gen
diff --git a/tests/exec_execve/Makefile b/tests/exec_execve/Makefile
new file mode 100644
index 0000000..97a4ce4
--- /dev/null
+++ b/tests/exec_execve/Makefile
@@ -0,0 +1,11 @@
+TARGETS=$(patsubst %.c,%,$(wildcard *.c))
+
+LDLIBS += -lpthread
+
+all: $(TARGETS)
+
+execve_arg_gen: execve_arg_gen.c
+ $(CC) $(CFLAGS) -o $@ $^
+
+clean:
+ rm -f $(TARGETS)
diff --git a/tests/exec_execve/execve_arg_gen.c b/tests/exec_execve/execve_arg_gen.c
new file mode 100644
index 0000000..a6da4d5
--- /dev/null
+++ b/tests/exec_execve/execve_arg_gen.c
@@ -0,0 +1,108 @@
+/**
+ * audit-testsuite EXECVE test tool
+ *
+ * Copyright (c) 2016 Red Hat <pmoore(a)redhat.com>
+ * Author: Paul Moore <paul(a)paul-moore.com>
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#define BADCHAR 0x20
+
+char **arg_setup(const char *name, unsigned int size)
+{
+ char **args = NULL;
+
+ args = malloc(sizeof(char *) * (size + 3));
+ if (!args)
+ exit(1);
+
+ args[0] = strdup("testing");
+ if (!args[0])
+ exit(1);
+ args[1] = strdup(name);
+ if (!args[1])
+ exit(1);
+
+ return args;
+}
+
+char *arg_gen(unsigned int length, char insert)
+{
+ int iter;
+ char val;
+ char *buf;
+
+ buf = malloc(length + 1);
+ if (!buf)
+ exit(1);
+
+ for (iter = 0; iter < length; iter++) {
+ if (insert && iter % 2) {
+ buf[iter] = insert;
+ } else {
+ /* ascii: 0x0..0xF */
+ val = iter % 0x10;
+ buf[iter] = (val > 9 ? 55 + val : 48 + val);
+ }
+ }
+ buf[length] = '\0';
+
+ return buf;
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ int iter;
+ int test_cfg;
+ char **exec_argv = NULL;
+
+ /* check if we are calling ourselves for testing purposes */
+ if ((argc >= 1) && (strcmp(argv[0], "testing") == 0))
+ return 0;
+
+ /* run a specific test? */
+ if (argc == 3) {
+ test_cfg = atoi(argv[2]);
+
+ if (strcmp(argv[1], "count") == 0) {
+ exec_argv = arg_setup("count", test_cfg);
+ for (iter = 0; iter < test_cfg; iter++)
+ exec_argv[iter + 2] = arg_gen(1, 0);
+ exec_argv[test_cfg + 2] = NULL;
+ } else if (strcmp(argv[1], "size") == 0) {
+ exec_argv = arg_setup("size", 1);
+ exec_argv[2] = arg_gen(test_cfg, 0);
+ exec_argv[3] = NULL;
+ } else if (strcmp(argv[1], "hex") == 0) {
+ exec_argv = arg_setup("hex", 1);
+ exec_argv[2] = arg_gen(test_cfg, BADCHAR);
+ exec_argv[3] = NULL;
+ }
+
+ rc = execve(argv[0], exec_argv, NULL);
+ return (rc < 0 ? errno : 0);
+ }
+
+ /* no idea what we were supposed to do */
+ return 2;
+}
diff --git a/tests/exec_execve/test b/tests/exec_execve/test
new file mode 100755
index 0000000..b16b0cd
--- /dev/null
+++ b/tests/exec_execve/test
@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+
+use strict;
+
+use Test;
+BEGIN { plan tests => 4 }
+
+use File::Temp qw/ tempfile /;
+
+my $basedir = $0;
+$basedir =~ s|(.*)/[^/]*|$1|;
+
+###
+# functions
+
+sub key_gen {
+ my @chars = ("A".."Z", "a".."z");
+ my $key = "testsuite-" . time . "-";
+ $key .= $chars[rand @chars] for 1..8;
+ return $key;
+}
+
+###
+# setup
+
+# reset audit
+system("auditctl -D >& /dev/null");
+
+# create stdout/stderr sinks
+(my $fh_out, my $stdout) = tempfile(TEMPLATE => '/tmp/audit-testsuite-out-XXXX',
+ UNLINK => 1);
+(my $fh_err, my $stderr) = tempfile(TEMPLATE => '/tmp/audit-testsuite-err-XXXX',
+ UNLINK => 1);
+(my $fh_out2, my $stdout2) = tempfile(
+ TEMPLATE => '/tmp/audit-testsuite-out-XXXX',
+ UNLINK => 1);
+(my $fh_err2, my $stderr2) = tempfile(
+ TEMPLATE => '/tmp/audit-testsuite-err-XXXX',
+ UNLINK => 1);
+
+###
+# tests
+
+# set the audit-by-executable filter
+my $key = key_gen();
+system("auditctl -a always,exit -F arch=b64 -S execve -k $key");
+system("auditctl -a always,exit -F arch=b32 -S execve -k $key");
+
+# test parameters
+my $test_count = 2048;
+my $test_size = 7499;
+my $test_hex = 6144;
+
+# run the tests
+system("$basedir/execve_arg_gen");
+system("$basedir/execve_arg_gen count $test_count");
+system("$basedir/execve_arg_gen size $test_size");
+system("$basedir/execve_arg_gen hex $test_hex");
+
+# test if we generate any audit records from the filter rule
+my $result = system("ausearch -i -k $key > $stdout 2> $stderr");
+ok($result, 0);
+
+# test if we generate the EXECVE records correctly
+my $line;
+my $line2;
+my $id;
+my $found_count = 0;
+my $found_size = 0;
+my $found_hex = 0;
+while ($line = <$fh_out>) {
+ if ($line =~ /^type=EXECVE /) {
+ if ($line =~ / a0=testing a1=count / ) {
+ ($id) = ($line =~ / msg=audit\(.*:([0-9]*)\).* /);
+ seek($fh_out2, 0, 0);
+ system("ausearch -i -k $key -a $id" .
+ " > $stdout2 2> $stderr2");
+ while ($line2 = <$fh_out2>) {
+ if ($line2 =~ /^type=EXECVE /) {
+ $found_count += () =
+ $line2 =~ /a([0-9])*=0/g;
+ }
+ }
+ } elsif ($line =~ / a0=testing a1=size / ) {
+ ($id) = ($line =~ / msg=audit\(.*:([0-9]*)\).* /);
+ seek($fh_out2, 0, 0);
+ system("ausearch -i -k $key -a $id" .
+ " > $stdout2 2> $stderr2");
+ while ($line2 = <$fh_out2>) {
+ if ($line2 =~ /^type=EXECVE / &&
+ $line2 =~ / a2(\[.*\])?=.* /) {
+ my $arg_iter;
+ my $arg_val;
+ ($arg_iter,$arg_val) = ($line2 =~
+ / a2(\[.*\])?=(.*) /);
+ $found_size += length $arg_val;
+ }
+ }
+ } elsif ($line =~ / a0=testing a1=hex / ) {
+ ($id) = ($line =~ / msg=audit\(.*:([0-9]*)\).* /);
+ seek($fh_out2, 0, 0);
+ system("ausearch -i -k $key -a $id" .
+ " > $stdout2 2> $stderr2");
+ while ($line2 = <$fh_out2>) {
+ if ($line2 =~ /^type=EXECVE / &&
+ $line2 =~ / a2(\[.*\])?=.* /) {
+ my $arg_iter;
+ my $arg_val;
+ ($arg_iter,$arg_val) = ($line2 =~
+ / a2(\[.*\])?=(.*) /);
+ $found_hex += length $arg_val;
+ }
+ }
+ }
+ }
+}
+ok($found_count == $test_count);
+ok($found_size == $test_size);
+ok($found_hex == $test_hex);
+
+###
+# cleanup
+
+system("auditctl -D >& /dev/null");
8 years, 3 months
[PATCH] field-dictionary: add ioctlcmd
by william.c.roberts@intel.com
From: William Roberts <william.c.roberts(a)intel.com>
Per-request ioctlcmd controls were added to SE Linux, however
the audit field dictionary was not updated.
This patch updates that dictionary.
Signed-off-by: William Roberts <william.c.roberts(a)intel.com>
---
specs/fields/field-dictionary.csv | 1 +
1 file changed, 1 insertion(+)
diff --git a/specs/fields/field-dictionary.csv b/specs/fields/field-dictionary.csv
index a645085..5a922e5 100644
--- a/specs/fields/field-dictionary.csv
+++ b/specs/fields/field-dictionary.csv
@@ -82,6 +82,7 @@ inode,numeric,inode number,
inode_gid,numeric,group id of the inode's owner,
inode_uid,numeric,user id of the inode's owner,
invalid_context,encoded,SELinux context,
+ioctlcmd,numeric,The request argument to the ioctl syscall,
ipx-net,numeric,IPX network number,
item,numeric,which item is being recorded,
items,numeric,the number of path records in the event,
--
1.9.1
8 years, 3 months
Re: [PATCH] selinux: print leading 0x on ioctlcmd audits
by Paul Moore
On Thu, Jul 14, 2016 at 3:29 PM, <william.c.roberts(a)intel.com> wrote:
> From: William Roberts <william.c.roberts(a)intel.com>
>
> ioctlcmd is currently printing hex numbers, but their is no leading
> 0x. Thus things like ioctlcmd=1234 are misleading, as the base is
> not evident.
>
> Correct this by adding 0x as a prefix, so ioctlcmd=1234 becomes ioctlcmd=0x1234.
>
> Signed-off-by: William Roberts <william.c.roberts(a)intel.com>
> ---
> security/lsm_audit.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
NOTE: adding Steve Grubb and the audit mailing list to the CC line
Like it or not, I believe the general standard/convention when it
comes to things like this is to leave off the "0x" prefix; the idea
being that is saves precious space in the audit logs and the value is
only ever going to be in hex anyway.
> diff --git a/security/lsm_audit.c b/security/lsm_audit.c
> index cccbf30..82e4dbb 100644
> --- a/security/lsm_audit.c
> +++ b/security/lsm_audit.c
> @@ -257,7 +257,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
> audit_log_format(ab, " ino=%lu", inode->i_ino);
> }
>
> - audit_log_format(ab, " ioctlcmd=%hx", a->u.op->cmd);
> + audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
> break;
> }
> case LSM_AUDIT_DATA_DENTRY: {
> --
> 1.9.1
>
> _______________________________________________
> Selinux mailing list
> Selinux(a)tycho.nsa.gov
> To unsubscribe, send email to Selinux-leave(a)tycho.nsa.gov.
> To get help, send an email containing "help" to Selinux-request(a)tycho.nsa.gov.
--
paul moore
www.paul-moore.com
8 years, 3 months
Weird issues in 2.6.5
by Chris Nandor
Hi, I had some odd behavior to report.
I am running ubuntu 12.04. Using the default auditd and audispd-plugins
packages for my release, I was able to get logs sent to local syslog and to
a remote auditd server (same basic configuration), but the entries were
being buffered somewhere (I think on the client side), and if the server
died reconnections didn't happen.
So, I wanted a more recent version, so I compiled audit-userspace from the
github src mirror,* trunk@1341.
When I did, I got some weird results. For example, I expected got
something like this in my audit.log:
node=host.example.com type=CWD msg=audit(1468363871.644:3279856):
cwd="/etc/audisp"
And that was as expected. In syslog, I expected to get:
Jul 13 08:34:53 host audispd: node=host.loc.example.com type=CWD
msg=audit(1468363871.644:3279856): cwd="/etc/audisp"
But instead, I got:
Jul 13 08:34:53 host audispd: type=CWD msg=node=host.loc.example.com
type=CWD msg=audit(1468363871.644
As you can see, the whole thing was prepended with "type=CWD msg=", and the
line was truncated. Similarly, on the remote host, I got the same thing:
type=CWD msg=node=host.loc.example.com type=CWD msg=audit(1468363871.644
I noticed that the most recent version of the src for ubuntu was 2.4.5, so
I grabbed the src tarball from packages.ubuntu and built it, and now
everything looks fine. The exact same line I see in my audit.log shows up
in the remote audit.log, with no buffering. When I restart the remote
auditd server or client, it reconnects. syslog has same entry (prepended
with the timestamp etc.). Everything seems happy now.
*For some reason I had to define `CC_FOR_BUILD=gcc` in my shell when I ran
`make` from the svn/git src. I did not require this when building 2.4.5
from the ubuntu src.
--Chris
8 years, 3 months
[PATCH] Fix whitespace in CWD record
by Steve Grubb
Fix the whitespace in the CWD record
Signed-off-by: Steve Grubb <sgrubb(a)redhat.com>
---
kernel/auditsc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -urp linux-4.7.0-0.rc4.git1.1.fc23.x86_64.orig/kernel/auditsc.c linux-4.7.0-0.rc4.git1.1.fc23.x86_64/kernel/auditsc.c
--- linux-4.7.0-0.rc4.git1.1.fc23.x86_64.orig/kernel/auditsc.c 2016-06-25 12:44:41.756440052 -0400
+++ linux-4.7.0-0.rc4.git1.1.fc23.x86_64/kernel/auditsc.c 2016-07-14 09:56:50.222227280 -0400
@@ -1426,7 +1426,7 @@ static void audit_log_exit(struct audit_
if (context->pwd.dentry && context->pwd.mnt) {
ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
if (ab) {
- audit_log_d_path(ab, " cwd=", &context->pwd);
+ audit_log_d_path(ab, "cwd=", &context->pwd);
audit_log_end(ab);
}
}
8 years, 3 months