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 <[email protected]> --- 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 <[email protected]> + * Author: Paul Moore <[email protected]> + */ + +/* + * 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"); -- Linux-audit mailing list [email protected] https://www.redhat.com/mailman/listinfo/linux-audit
