Skip to content

Commit

Permalink
tests: add test for contid
Browse files Browse the repository at this point in the history
See: linux-audit#64

Signed-off-by: Richard Guy Briggs <[email protected]>
  • Loading branch information
rgbriggs committed Apr 10, 2019
1 parent 38f7a5f commit dbd3f2e
Show file tree
Hide file tree
Showing 3 changed files with 313 additions and 0 deletions.
1 change: 1 addition & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ endif

# all of the tests
TESTS := \
containerid \
exec_execve \
exec_name \
file_create \
Expand Down
8 changes: 8 additions & 0 deletions tests/containerid/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
TARGETS=$(patsubst %.c,%,$(wildcard *.c))

LDLIBS += -lpthread

all: $(TARGETS)
clean:
rm -f $(TARGETS)

304 changes: 304 additions & 0 deletions tests/containerid/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
#!/usr/bin/perl

use strict;
use File::Temp qw/ tempdir tempfile /;
use Test;
BEGIN { plan tests => 15 } # 5 + 10 main loop iterations

###
# functions

sub key_gen {
my @chars = ( "A" .. "Z", "a" .. "z" );
my $key = "testsuite-" . time . "-";
$key .= $chars[ rand @chars ] for 1 .. 8;
return $key;
}

sub mark_gen {
my @chars = ( "A" .. "Z", "a" .. "z" );
my $key = "testsuite-" . time . "-";
$key .= $chars[ rand @chars ] for 1 .. 8;
return $key;
}

###
# setup

# reset audit rules
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_tmp, my $tmpout ) = tempfile(
TEMPLATE => '/tmp/audit-testsuite-tmp-XXXX',
UNLINK => 1
);

my $key = key_gen();
my $result;

my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
localtime(time);
$year += 1900;
$mon += 1;
my $startdate = "$year-$mon-$mday";
my $starttime = "$hour:$min:$sec";

my $contid_unset = 18446744073709551615;
my $contid1 = int( rand( 1 << 63 ) );
my $contid2 = int( rand( 1 << 63 ) );
my $contid3 = int( rand( 1 << 63 ) );
my $contid4 = int( rand( 1 << 63 ) );
my $contid5 = int( rand( 1 << 63 ) );
my $contid6 = int( rand( 1 << 63 ) );
my $contid7 = int( rand( 1 << 63 ) );

###
# tests
# Test self-set
# Start sleep to provide target tasks
seek( $fh_out, 0, 0 );
system("sleep 2 >/dev/null 2>&1 & echo \$! >$stdout");
my $task1_pid = <$fh_out>;
chomp($task1_pid);

# Set the audit container identifier and save the pid responsible
seek( $fh_out, 0, 0 );
$result = system(
"echo $contid1 > /proc/self/audit_containerid >/dev/null 2>&1 & echo \$! >$stdout"
);
ok( $result, 0 );
my $self_pid = <$fh_out>;
chomp($self_pid);

# Test unset
$result = system("echo $contid_unset > /proc/$task1_pid/audit_containerid");
ok( $result != 0 ); # Did unset fail?

# Test set
$result = system("echo $contid2 > /proc/$task1_pid/audit_containerid");
ok( $result, 0 ); # Did set succeed?

# Test set again
$result = system("echo $contid3 > /proc/$task1_pid/audit_containerid");
ok( $result, 0 ); # Did set again succeed?

# Test child with child fail
#FIXME, doesn't spawn child of child
seek( $fh_tmp, 0, 0 );
system("bash -c \"sleep 2\" >/dev/null 2>&1 & echo \$! >$tmpout");
my $task2_pid = <$fh_tmp>;
chomp($task2_pid);
$result = system("echo $contid4 > /proc/$task2_pid/audit_containerid");
ok( $result != 0 ); # Did set with child fail?

seek( $fh_out, 0, 0 );
seek( $fh_err, 0, 0 );
$result = system(
"ausearch -i -ts boot -m container_op --contid=$contid1 >$stdout 2>$stderr"
);
ok( $result, 0 ); # Was an event found?

seek( $fh_tmp, 0, 0 );
system("command >/dev/null 2>&1 & echo \$! >$tmpout");
my $command_pid = <$fh_tmp>;
chomp($command_pid);

## Add rule to ...
#$result =
#system("auditctl -a exit,always -F arch=b$ENV{MODE} ... -F key=$key >/dev/null 2>&1");
#ok( $result, 0 ); # Was the rule added successfully?
#sleep 1;
#kill 'TERM', $ping_pid;
#system("auditctl -d exit,always -F arch=b$ENV{MODE} ... -F key=$key >/dev/null 2>&1");

# find the event
seek( $fh_out, 0, 0 );
seek( $fh_err, 0, 0 );
$result = system("ausearch -ts recent -i -m CONTAINER_OP >$stdout 2>$stderr");
ok( $result, 0 ); # Was an event found?

# test if we generate the lost reset record correctly
my $line;
my $contid1_found = 0;
my $contid_unset_found = 0;
my $contid2_found = 0;
my $contid3_found = 0;
my $contid4_found = 0;
while ( $line = <$fh_out> ) {
if ( $line =~ /^type=CONTAINER_OP / ) {
if ( $line =~ / opid=([0-9]+) contid=([0-9]+) / ) {
if ( $1 == $self_pid && $2 == $contid1 ) {
$contid1_found = 1;
}
elsif ( $1 == $task1_pid && $2 == $contid_unset ) {
$contid_unset_found = 1;
}
elsif ( $1 == $task1_pid && $2 == $contid2 ) {
$contid2_found = 1;
}
elsif ( $1 == $task1_pid && $2 == $contid3 ) {
$contid3_found = 1;
}
elsif ( $1 == $task2_pid && $2 == $contid4 ) {
$contid4_found = 1;
}
}
}
}
ok( $contid1_found, 1 ); # Was the contid1 message well-formed?
ok( $contid_unset_found, 1 ); # Was the contid_unset message well-formed?
ok( $contid2_found, 1 ); # Was the contid2 message well-formed?
ok( $contid3_found, 1 ); # Was the contid3 message well-formed?
ok( $contid4_found, 1 ); # Was the contid4 message well-formed?

# Test filter on containerid
$result = system(
"auditctl -a exit,always -F arch=b$ENV{MODE} -F dir=/tmp -F perm=wa -F contid=$contid5 -F key=$key >/dev/null 2>&1"
);
ok( $result, 0 ); # Filter rule added successfully?
seek( $fh_out, 0, 0 );
$result = system(
"perl -e \"sleep 1; open(my \$tmpfile, '>', \\"/tmp/$key\\"); close(\$tmpfile);\" >/dev/null 2>&1 & echo \$! >$stdout"
);
ok( $result, 0 ); # Was the filter trigger successfully run?
my $task3_pid = <$fh_out>;
chomp($task3_pid);
$result =
system("echo $contid5 > /proc/$task3_pid/audit_containerid >/dev/null 2>&1");
ok( $result, 0 ); # Was the audit container identifier set successful?
sleep 1;
unlink "/tmp/$key";
system(
"auditctl -d exit,always -F arch=b$ENV{MODE} -F dir=/tmp -F perm=wa -F contid=$contid5 -F key=$key >/dev/null 2>&1"
);

# find the event
seek( $fh_out, 0, 0 );
seek( $fh_err, 0, 0 );
$result =
system("ausearch -ts recent -i -m CONTAINER_ID -k $key >$stdout 2>$stderr");
ok( $result, 0 ); # Was an event found?
my $contid5_found = 0;
while ( $line = <$fh_out> ) {
if ( $line =~ /^type=CONTAINER_ID / ) {
if ( $line =~ / contid=([0-9]+) / ) {
if ( $1 == $contid5 ) {
$contid5_found = 1;
}
}
}
}
ok( $contid5_found, 1 ); # Was the contid5 message well-formed?

# Test multiple containers on one netns
# Create two child processes
seek( $fh_out, 0, 0 );
system("sleep 2 >/dev/null 2>&1 & echo \$! >$stdout");
my $task4_pid = <$fh_out>;
chomp($task4_pid);
$result =
system("echo $contid6 > /proc/$task4_pid/audit_containerid >/dev/null 2>&1");
ok( $result, 0 ); # Was contid6 written to task4?
seek( $fh_out, 0, 0 );
system("sleep 2 >/dev/null 2>&1 & echo \$! >$stdout");
my $task5_pid = <$fh_out>;
chomp($task5_pid);
$result =
system("echo $contid7 > /proc/$task5_pid/audit_containerid >/dev/null 2>&1");
ok( $result, 0 ); # Was contid7 written to task5?

# Set up audit rules in netfilter and send a test packet
my $mark = int( rand(99999999) );
$result = system(
"iptables -I INPUT -i lo -p icmp --icmp-type echo-request -j AUDIT --type accept >/dev/null 2>&1"
);
ok( $result, 0 ); # Was the iptables filter rule added successful
$result = system(
"iptables -I INPUT -t mangle -i lo -p icmp --icmp-type echo-request -j MARK --set-mark 0x$mark >/dev/null 2>&1"
);
ok( $result, 0 ); # Was the iptables mangle rule added successful
sleep 1;
$result = system("ping -q -c 1 127.0.0.1 >/dev/null 2>&1");
ok( $result, 0 ); # Was ping successful?
sleep 1;
system(
"iptables -D INPUT -i lo -p icmp --icmp-type echo-request -j AUDIT --type accept >/dev/null 2>&1"
);
system(
"iptables -D INPUT -t mangle -i lo -p icmp --icmp-type echo-request -j MARK --set-mark 0x$mark >/dev/null 2>&1"
);

# find the event
seek( $fh_out, 0, 0 );
seek( $fh_err, 0, 0 );
$result = system("ausearch -ts recent -i -m NETFILTER_PKT >$stdout 2>$stderr");
ok( $result, 0 ); # Was an event found?
my $contid6_found = 0;
my $contid7_found = 0;
my $id = "";
while ( $line = <$fh_out> ) {

if ( $line =~ /^type=NETFILTER_PKT / ) {
if ( $line =~ / mark=0x$mark / ) {
($id) = ( $line =~ / msg=audit\(.*:([0-9]*)\).* / );
}
}
}
seek( $fh_out, 0, 0 );
seek( $fh_err, 0, 0 );
$result = system("ausearch -ts boot -i -a $id >$stdout 2>$stderr");
ok( $result, 0 ); # Was an event found?
while ( $line = <$fh_out> ) {
if ( $line =~ /^type=CONTAINER_ID / ) {
if ( $line =~ / contid=([,0-9]+) / ) {
if ( $1 =~ /$contid6/ ) {
$contid6_found = 1;
}
if ( $1 =~ /$contid7/ ) {
$contid7_found = 1;
}
}
}
}
ok( $contid6_found, 1 ); # Was the contid6 message well-formed?
ok( $contid7_found, 1 ); # Was the contid7 message well-formed?

if ( defined $ENV{ATS_DEBUG} && $ENV{ATS_DEBUG} == 1 ) {
if ( !$contid1_found ) {
print "self_pid=$self_pid contid1=$contid1\n";
}
if ( !$contid_unset_found ) {
print "task1_pid=$task1_pid contid_unset=$contid_unset\n";
}
if ( !$contid2_found ) {
print "task1_pid=$task1_pid contid2=$contid2\n";
}
if ( !$contid3_found ) {
print "task1_pid=$task1_pid contid3=$contid3\n";
}
if ( !$contid4_found ) {
print "task2_pid=$task2_pid contid4=$contid4\n";
}
if ( !$contid5_found ) {
print "task3_pid=$task3_pid contid5=$contid5\n";
}
if ( !$contid6_found ) {
print "mark=$mark id=$id contid6=$contid6\n";
}
if ( !$contid5_found ) {
print "mark=$mark id=$id contid7=$contid7\n";
}
}

###
# cleanup
system("service auditd restart 2>/dev/null");

0 comments on commit dbd3f2e

Please sign in to comment.