forked from linux-audit/audit-testsuite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
See: linux-audit#64 Signed-off-by: Richard Guy Briggs <[email protected]>
- Loading branch information
Showing
3 changed files
with
313 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ endif | |
|
||
# all of the tests | ||
TESTS := \ | ||
containerid \ | ||
exec_execve \ | ||
exec_name \ | ||
file_create \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |