[audit-testsuite PATCH] exec_execve: add some simple tests for the EXECVE record

Paul Moore pmoore at redhat.com
Wed Jul 20 18:44:40 UTC 2016


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 at 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 at redhat.com>
+ * Author: Paul Moore <paul at 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");




More information about the Linux-audit mailing list