From f9733c5a2b921910e09317f31194979939a24258 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Fri, 5 Apr 2019 15:08:03 -0400 Subject: [PATCH 1/4] tests: add test for contid See: https://github.com/linux-audit/audit-testsuite/issues/64 Signed-off-by: Richard Guy Briggs --- tests/Makefile | 1 + tests/containerid/Makefile | 8 + tests/containerid/test | 420 +++++++++++++++++++++++++++++++++++++ 3 files changed, 429 insertions(+) create mode 100644 tests/containerid/Makefile create mode 100755 tests/containerid/test diff --git a/tests/Makefile b/tests/Makefile index 1701fc1..72dff41 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -14,6 +14,7 @@ endif # all of the tests TESTS := \ backlog_wait_time_actual_reset \ + containerid \ exec_execve \ exec_name \ file_create \ diff --git a/tests/containerid/Makefile b/tests/containerid/Makefile new file mode 100644 index 0000000..7ade09a --- /dev/null +++ b/tests/containerid/Makefile @@ -0,0 +1,8 @@ +TARGETS=$(patsubst %.c,%,$(wildcard *.c)) + +LDLIBS += -lpthread + +all: $(TARGETS) +clean: + rm -f $(TARGETS) + diff --git a/tests/containerid/test b/tests/containerid/test new file mode 100755 index 0000000..be8bbaf --- /dev/null +++ b/tests/containerid/test @@ -0,0 +1,420 @@ +#!/usr/bin/perl + +use strict; +use File::Temp qw/ tempdir tempfile /; +use Test; +use IO::Handle; +BEGIN { plan tests => 34 } + +### +# 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 + +chomp( my $abi_bits = $ENV{MODE} != 0 ? $ENV{MODE} : `getconf LONG_BIT` ); + +# 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 $tmpdir = tempdir( + TEMPLATE => '/tmp/audit-testsuite-dir-XXXX', + CLEANUP => 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 $contidself = int( rand( 1 << 63 ) ); +my $contid1 = int( rand( 1 << 63 ) ); +my $contid_unset = 18446744073709551615; +my $contid1a = int( rand( 1 << 63 ) ); +my $contid2 = int( rand( 1 << 63 ) ); +my $contidfilt = int( rand( 1 << 63 ) ); +my $contid1net = int( rand( 1 << 63 ) ); +my $contid2net = int( rand( 1 << 63 ) ); + +### +# tests +################################################################################ +# Test self-set +seek( $fh_out, 0, 0 ); + +# Set the audit container identifier and save the pid responsible +my $resultself; +my $self_pid = fork(); +if ( not $self_pid ) { + open( my $contidfd, '>', "/proc/self/audit_containerid" ); + $contidfd->autoflush(1); + $resultself = print $contidfd $contidself; + if ( not $resultself ) { + $resultself = $!; + } + close($contidfd); + exit $resultself; +} +wait(); +$resultself = $? >> 8; +ok( $self_pid > 0 ); # Did taskself start ok? +ok( $resultself != 1 ); # Did self-set fail? + +# Start sleep to provide target task +my $task1_pid = fork(); +if ( not $task1_pid ) { + sleep 2; + exit; +} +sleep .01; +ok( $task1_pid > 0 ); # Did task1 start ok? + +################################################################################ +# Test set +open( my $contidfd, '>', "/proc/$task1_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd "$contid1\n"; +close($contidfd); +ok($result); # Did set succeed? + +################################################################################ +# Test set same +open( $contidfd, '>', "/proc/$task1_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd "$contid1\n"; +close($contidfd); +ok( not $result ); # Did set same fail? + +################################################################################ +# Test unset +open( $contidfd, '>', "/proc/$task1_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contid_unset; +close($contidfd); +ok( not $result ); # Did unset fail? + +################################################################################ +# Test set again by same orch +open( $contidfd, '>', "/proc/$task1_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contid1a; +close($contidfd); +ok( not $result ); # Did set again fail? + +################################################################################ +# Test task injection to existing container +# Start sleep to provide injection target task +my $task1a_pid = fork(); +if ( not $task1a_pid ) { + sleep 2; + exit; +} +sleep .01; +ok( $task1a_pid > 0 ); # Did task1a start ok? + +# Test task injection +open( $contidfd, '>', "/proc/$task1a_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd "$contid1\n"; +close($contidfd); +ok($result); # Did injection succeed? + +################################################################################ +# Test child with child fail +my $task2_pid = fork(); +if ( not $task2_pid ) { + my $task2child_pid = fork(); + if ( not $task2child_pid ) { + sleep 2; + exit; + } + wait(); + exit; +} +sleep 1; +open( $contidfd, '>', "/proc/$task2_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contid2; +close($contidfd); +ok( not $result ); # Did set child with child fail? +ok( $task2_pid > 0 ); # Did task2 start ok? + +# make sure the records had a chance to bubble through to the logs +system("auditctl -m sync-$key"); +for ( my $i = 0 ; $i < 10 ; $i++ ) { + if ( system("ausearch -m USER 2> /dev/null | grep -q sync-$key") eq 0 ) { + last; + } + sleep(0.2); +} + +# find the op events +seek( $fh_out, 0, 0 ); +seek( $fh_err, 0, 0 ); +$result = system( +"LC_TIME=\"en_DK.utf8\" ausearch -ts $startdate $starttime -m CONTAINER_OP >$stdout 2>$stderr" +); +ok( $result, 0 ); # Was an event found? + +# test if we generate the op record correctly +my $line; +my $contidself_found = 0; +my $contid1_found = 0; +my $contid_unset_found = 0; +my $contid1a_found = 0; +my $contid1i_found = 0; +my $contid2_found = 0; + +while ( $line = <$fh_out> ) { + + if ( $line =~ /^type=CONTAINER_OP / ) { + if ( $line =~ / opid=([0-9]+) contid=([0-9]+) / ) { + if ( $1 == $self_pid && $2 == $contidself ) { + $contidself_found = 1; + } + elsif ( $1 == $task1_pid && $2 == $contid1 ) { + $contid1_found = 1; + } + elsif ( $1 == $task1_pid && $2 == $contid_unset ) { + $contid_unset_found = 1; + } + elsif ( $1 == $task1_pid && $2 == $contid1a ) { + $contid1a_found = 1; + } + elsif ( $1 == $task1a_pid && $2 == $contid1 ) { + $contid1i_found = 1; + } + elsif ( $1 == $task2_pid && $2 == $contid2 ) { + $contid2_found = 1; + } + } + } +} +ok( $contidself_found, 1 ); # Was the contidself message well-formed? +ok( $contid1_found, 1 ); # Was the contid1 message well-formed? +ok( $contid_unset_found, 1 ); # Was the contid_unset message well-formed? +ok( $contid1a_found, 1 ); # Was the contid1a message well-formed? +ok( $contid1i_found, 1 ); # Was the contid1i message well-formed? +ok( $contid2_found, 1 ); # Was the contid2 message well-formed? + +# Test filter on containerid +$result = system( +"auditctl -a exit,always -F arch=b$abi_bits -F dir=$tmpdir -F perm=wa -F contid=$contidfilt -F key=$key >/dev/null 2>&1" +); +ok( $result, 0 ); # Filter rule added successfully? +my $taskfilt_pid = fork(); +if ( not $taskfilt_pid ) { + sleep 1; + open( $contidfd, '>', "$tmpdir/$key" ); + $contidfd->autoflush(1); + print $contidfd $contidfilt; + close($contidfd); + exit; +} +sleep .01; +open( $contidfd, '>', "/proc/$taskfilt_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contidfilt; +close($contidfd); +ok($result); # Was the filter trigger successfully run? +ok( $taskfilt_pid > 0 ); # Did taskfilt start ok? +sleep 1; +system( +"auditctl -d exit,always -F arch=b$abi_bits -F dir=$tmpdir -F perm=wa -F contid=$contidfilt -F key=$key >/dev/null 2>&1" +); + +# make sure the records had a chance to bubble through to the logs +system("auditctl -m sync2-$key"); +for ( my $i = 0 ; $i < 10 ; $i++ ) { + if ( system("ausearch -m USER 2> /dev/null | grep -q sync2-$key") eq 0 ) { + last; + } + sleep(0.2); +} + +# 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 $contidfilt_found = 0; +while ( $line = <$fh_out> ) { + if ( $line =~ /^type=CONTAINER_ID / ) { + if ( $line =~ / contid=([0-9]+)/ ) { + if ( $1 == $contidfilt ) { + $contidfilt_found = 1; + } + } + } +} +ok( $contidfilt_found, 1 ); # Was the contidfilt message well-formed? + +################################################################################ +# Test multiple containers on one netns +# Create two child processes +my $task1net_pid = fork(); +if ( not $task1net_pid ) { + sleep 2; + exit; +} +ok( $task1net_pid > 0 ); # Did task1net start ok? +sleep .01; +open( $contidfd, '>', "/proc/$task1net_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contid1net; +close($contidfd); +ok($result); # Was contid1net written to task1net? + +my $task2net_pid = fork(); +if ( not $task2net_pid ) { + sleep 2; + exit; +} +ok( $task2net_pid > 0 ); # Did task2net start ok? +sleep .01; +open( $contidfd, '>', "/proc/$task2net_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contid2net; +close($contidfd); +ok($result); # Was contid2net written to task2net? + +# 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" +); + +# make sure the records had a chance to bubble through to the logs +system("auditctl -m sync3-$key"); +for ( my $i = 0 ; $i < 10 ; $i++ ) { + if ( system("ausearch -m USER 2> /dev/null | grep -q sync3-$key") eq 0 ) { + last; + } + sleep(0.2); +} + +# find the event +seek( $fh_out, 0, 0 ); +seek( $fh_err, 0, 0 ); +$result = system( +"LC_TIME=\"en_DK.utf8\" ausearch -ts $startdate $starttime -i -m NETFILTER_PKT >$stdout 2>$stderr" +); +ok( $result, 0 ); # Was an event found? +my $contid1net_found = 0; +my $contid2net_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 -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]+)/ ) { + my $contids = $1; + if ( $contids =~ /$contid1net/ ) { + $contid1net_found = 1; + } + if ( $contids =~ /$contid2net/ ) { + $contid2net_found = 1; + } + } + } +} +ok( $contid1net_found, 1 ); # Was the contid1net message well-formed? +ok( $contid2net_found, 1 ); # Was the contid2net message well-formed? + +################################################################################ +# Debug +if ( defined $ENV{ATS_DEBUG} && $ENV{ATS_DEBUG} == 1 ) { + print "\ndebug: start\n"; + if ( !$contidself_found || !$resultself ) { + print + "self_pid=$self_pid contidself=$contidself resultself=$resultself\n"; + } + if ( !$contid1_found ) { + print "task1_pid=$task1_pid contid1=$contid1\n"; + } + if ( !$contid_unset_found ) { + print "task1_pid=$task1_pid contid_unset=$contid_unset\n"; + } + if ( !$contid1a_found ) { + print "task1_pid=$task1_pid contid1a=$contid1a\n"; + } + if ( !$contid1i_found ) { + print "task1a_pid=$task1a_pid contid1i=$contid1\n"; + } + if ( !$contid2_found ) { + print "task2_pid=$task2_pid contid2=$contid2\n"; + } + if ( !$contidfilt_found ) { + print "taskfilt_pid=$taskfilt_pid contidfilt=$contidfilt dir=$tmpdir key=$key\n"; + } + if ( !$contid1net_found ) { + print "mark=$mark id=$id contid1net=$contid1net\n"; + } + if ( !$contid2net_found ) { + print "mark=$mark id=$id contid2net=$contid2net\n"; + } + print "debug: end\n\n\n"; +} + +### +# cleanup +system("service auditd restart 2>/dev/null"); From a77cca96b36799e6de33c699e7ce05c3d329b23a Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Thu, 27 Jun 2019 11:44:41 -0400 Subject: [PATCH 2/4] tests: move containerid test to last to avoid net lockup in netfilter_pkt test Signed-off-by: Richard Guy Briggs --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 72dff41..64783b2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -14,7 +14,6 @@ endif # all of the tests TESTS := \ backlog_wait_time_actual_reset \ - containerid \ exec_execve \ exec_name \ file_create \ @@ -30,6 +29,7 @@ TESTS := \ syscall_module \ syscall_socketcall \ time_change \ + containerid \ user_msg \ fanotify \ bpf From 81f4e03d2131020cac1ef4c6cfa0d8592092e33a Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 11 Sep 2019 17:37:15 -0400 Subject: [PATCH 3/4] tests: contid: add test for capcontid Signed-off-by: Richard Guy Briggs --- tests/containerid/test | 48 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/containerid/test b/tests/containerid/test index be8bbaf..ab95f45 100755 --- a/tests/containerid/test +++ b/tests/containerid/test @@ -4,7 +4,9 @@ use strict; use File::Temp qw/ tempdir tempfile /; use Test; use IO::Handle; -BEGIN { plan tests => 34 } +use Sys::Syscall; #perl-Sys-Syscall.noarch +require 'syscall.ph'; +BEGIN { plan tests => 37 } ### # functions @@ -67,6 +69,7 @@ my $contid2 = int( rand( 1 << 63 ) ); my $contidfilt = int( rand( 1 << 63 ) ); my $contid1net = int( rand( 1 << 63 ) ); my $contid2net = int( rand( 1 << 63 ) ); +my $contidcap = int( rand( 1 << 63 ) ); ### # tests @@ -380,6 +383,46 @@ while ( $line = <$fh_out> ) { ok( $contid1net_found, 1 ); # Was the contid1net message well-formed? ok( $contid2net_found, 1 ); # Was the contid2net message well-formed? +################################################################################ +# Test capcontid set +# Start sleep to provide target task +my $taskcap_pid = fork(); +my $resultcap; +if ( not $taskcap_pid ) { + $! = 0; + $result = syscall( &SYS_unshare, 0x10000000 ); #CLONE_NEWUSER + if ( $result == -1 && $1 == 0 ) { + print "syscall SYS_unshare failed with errno:" . $! . "\n"; + } + sleep 2; + my $taskcapchild_pid = fork(); + if ( not $taskcapchild_pid ) { + sleep 2; + exit; + } + open( my $contidfd, '>', "/proc/$taskcapchild_pid/audit_containerid" ); + $contidfd->autoflush(1); + $resultcap = print $contidfd $contidcap; + close($contidfd); + if ( not $resultcap ) { + $resultcap = $!; + } + close($contidfd); + exit $resultcap; +} +sleep 1; + +# Test set +open( $contidfd, '>', "/proc/$taskcap_pid/audit_capcontainerid" ); +$contidfd->autoflush(1); +$result = print $contidfd "1\n"; +close($contidfd); +ok($result); # Did set capchild without init cap fail? +ok( $taskcap_pid > 0 ); # Did taskcap start ok? +my $wait_cap = wait(); +$resultcap = $? >> 8; +ok( $resultcap != 1 ); # Did set fail with capcontid? + ################################################################################ # Debug if ( defined $ENV{ATS_DEBUG} && $ENV{ATS_DEBUG} == 1 ) { @@ -412,6 +455,9 @@ if ( defined $ENV{ATS_DEBUG} && $ENV{ATS_DEBUG} == 1 ) { if ( !$contid2net_found ) { print "mark=$mark id=$id contid2net=$contid2net\n"; } + if ( !$resultcap != 1 ) { + print "taskcap_pid=$taskcap_pid resultcap=$resultcap\n"; + } print "debug: end\n\n\n"; } From 4125fce3902fe70623eb1e9b28b54d7b63bfca3c Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Wed, 21 Oct 2020 20:10:56 -0400 Subject: [PATCH 4/4] tests/containerid: add support for signals Signed-off-by: Richard Guy Briggs --- tests/containerid/test | 220 ++++++++++++++++++++++++++++++++++++--- tests/netfilter_pkt/test | 3 + 2 files changed, 207 insertions(+), 16 deletions(-) diff --git a/tests/containerid/test b/tests/containerid/test index ab95f45..35b98a3 100755 --- a/tests/containerid/test +++ b/tests/containerid/test @@ -6,7 +6,7 @@ use Test; use IO::Handle; use Sys::Syscall; #perl-Sys-Syscall.noarch require 'syscall.ph'; -BEGIN { plan tests => 37 } +BEGIN { plan tests => 52 } ### # functions @@ -66,6 +66,10 @@ my $contid1 = int( rand( 1 << 63 ) ); my $contid_unset = 18446744073709551615; my $contid1a = int( rand( 1 << 63 ) ); my $contid2 = int( rand( 1 << 63 ) ); +my $contidsig = int( rand( 1 << 63 ) ); +my $contidsigc = int( rand( 1 << 63 ) ); +my $contidsigc2 = int( rand( 1 << 63 ) ); +my $contidsigk = int( rand( 1 << 63 ) ); my $contidfilt = int( rand( 1 << 63 ) ); my $contid1net = int( rand( 1 << 63 ) ); my $contid2net = int( rand( 1 << 63 ) ); @@ -158,8 +162,8 @@ ok($result); # Did injection succeed? # Test child with child fail my $task2_pid = fork(); if ( not $task2_pid ) { - my $task2child_pid = fork(); - if ( not $task2child_pid ) { + my $task2c_pid = fork(); + if ( not $task2c_pid ) { sleep 2; exit; } @@ -173,7 +177,99 @@ $result = print $contidfd $contid2; close($contidfd); ok( not $result ); # Did set child with child fail? ok( $task2_pid > 0 ); # Did task2 start ok? +################################################################################ +# Test task group signal + +my $resultsig = 0; +my $tasksigc_pid = 0; +my $tasksigc2_pid = 0; +my $tasksig_pid = fork(); +if ( not $tasksig_pid ) { + setpgrp; + sleep 2; # wait for parent to set contid + + $tasksigc_pid = fork(); + if ( not $tasksigc_pid ) { + sleep 10; + exit; + } + + $tasksigc2_pid = fork(); + if ( not $tasksigc2_pid ) { + sleep 10; + exit; + } + sleep 1; # wait for child of child to start + + # set nested child with different contid + my $contidfd; + open( $contidfd, '>', "/proc/$tasksigc_pid/audit_containerid" ); + $contidfd->autoflush(1); + $resultsig = print $contidfd $contidsigc; + close($contidfd); + if ( not $resultsig ) { + $resultsig = $!; + } + close($contidfd); + + open( $contidfd, '>', "/proc/$tasksigc2_pid/audit_containerid" ); + $contidfd->autoflush(1); + $resultsig = print $contidfd $contidsigc2; + close($contidfd); + if ( not $resultsig ) { + $resultsig = $!; + } + close($contidfd); + + wait(); + exit $resultsig; +} + +sleep 1; # wait for child to start +ok( $tasksig_pid > 0 ); # Did tasksig start ok? +open( $contidfd, '>', "/proc/$tasksig_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contidsig; +close($contidfd); +ok($result); # Did set child succeed? +sleep 1; # wait for grandchild to start and get contid set + +# generate kill signal child +my $tasksigk_pid = fork(); +if ( not $tasksigk_pid ) { + sleep 2; # wait for parent to set contid + my $count = kill 'SIGTERM', -$tasksig_pid; + exit 0; +} +ok( $tasksigk_pid > 0 ); # Did tasksigk start ok? + +# Add rule to catch signals generated by kill child +$result = + system( +"auditctl -a exit,always -F arch=b$ENV{MODE} -S kill -F pid=$tasksigk_pid -F key=$key >/dev/null 2>&1" + ); +ok( $result, 0 ); # Was the rule accepted? +sleep 1; # wait for kill child to start +open( $contidfd, '>', "/proc/$tasksigk_pid/audit_containerid" ); +$contidfd->autoflush(1); +$result = print $contidfd $contidsigk; +close($contidfd); +ok($result); # Did set kill child succeed? +sleep 2; + +# Wait for result of setting nested children +my $wait_pid = waitpid( $tasksig_pid, 0 ); +if ( $wait_pid == $tasksig_pid ) { + $resultsig = $? >> 8; +} +ok( $resultsig != 1 ); # Did sig-set fail? + +# Delete audit rule +system( +"auditctl -d exit,always -F arch=b$ENV{MODE} -S kill -F pid=$tasksigk_pid -F key=$key >/dev/null 2>&1" +); +################################################################################ # make sure the records had a chance to bubble through to the logs system("auditctl -m sync-$key"); for ( my $i = 0 ; $i < 10 ; $i++ ) { @@ -232,11 +328,88 @@ ok( $contid1a_found, 1 ); # Was the contid1a message well-formed? ok( $contid1i_found, 1 ); # Was the contid1i message well-formed? ok( $contid2_found, 1 ); # Was the contid2 message well-formed? +# find the id events +seek( $fh_out, 0, 0 ); +seek( $fh_err, 0, 0 ); +$result = system( +"LC_TIME=\"en_DK.utf8\" ausearch -i -ts $startdate $starttime -m CONTAINER_ID >$stdout 2>$stderr" +); +ok( $result, 0 ); # Was an event found? + +# test if we generate the id record correctly +my $contidsig_found = 0; +my $contidsigc_found = 0; +my $contidsigc2_found = 0; +my $contidsigk_found = 0; +my $recsig_found = 0; +my $recsigc_found = 0; +my $recsigc2_found = 0; +my $recsigk_found = 0; +my $tasksig_rec = 0; +my $tasksigc_rec = 0; +my $tasksigc2_rec = 0; +my $tasksigk_rec = 0; + +while ( $line = <$fh_out> ) { + if ( $line =~ /^type=CONTAINER_ID / ) { + chomp $line; + if ( $line =~ / record=([0-9]+) contid=$contidsig $/ ) { + $contidsig_found = 1; + $tasksig_rec = $1; + } + elsif ( $line =~ / record=([0-9]+) contid=$contidsigc,/ ) { + $tasksigc_rec = $1; + $contidsigc_found = 1; + } + elsif ( $line =~ / record=([0-9]+) contid=$contidsigc2,/ ) { + $tasksigc2_rec = $1; + $contidsigc2_found = 1; + } + elsif ( $line =~ / record=([0-9]+) contid=$contidsigk $/ ) { + $tasksigk_rec = $1; + $contidsigk_found = 1; + } + } +} +seek( $fh_out, 0, 0 ); +while ( $line = <$fh_out> ) { + if ( $line =~ /^type=SYSCALL / ) { + chomp $line; + if ( $line =~ / pid=$tasksigk_pid .+ record=$tasksigk_rec $/ ) { + $recsigk_found = 1; + } + } + elsif ( $line =~ /^type=OBJ_PID / ) { + chomp $line; + if ( $line =~ / opid=([0-9]+) .+ record=$tasksig_rec $/ ) { + $tasksig_pid = $1; + $recsig_found = 1; + } + elsif ( $line =~ / opid=([0-9]+) .+ record=$tasksigc_rec $/ ) { + $tasksigc_pid = $1; + $recsigc_found = 1; + } + elsif ( $line =~ / opid=([0-9]+) .+ record=$tasksigc2_rec $/ ) { + $tasksigc2_pid = $1; + $recsigc2_found = 1; + } + } +} +ok( $contidsig_found, 1 ); # Was the contidsig message well-formed? +ok( $contidsigc_found, 1 ); # Was the contidsigc message well-formed? +ok( $contidsigc2_found, 1 ); # Was the contidsigc message well-formed? +ok( $contidsigk_found, 1 ); # Was the contidsigk message well-formed? +ok( $recsig_found, 1 ); # Was the recsig message well-formed? +ok( $recsigc_found, 1 ); # Was the recsigc message well-formed? +ok( $recsigc2_found, 1 ); # Was the recsigc message well-formed? +ok( $recsigk_found, 1 ); # Was the recsigk message well-formed? + +################################################################################ # Test filter on containerid $result = system( "auditctl -a exit,always -F arch=b$abi_bits -F dir=$tmpdir -F perm=wa -F contid=$contidfilt -F key=$key >/dev/null 2>&1" ); -ok( $result, 0 ); # Filter rule added successfully? +ok( $result, 0 ); # Filter rule added successfully? my $taskfilt_pid = fork(); if ( not $taskfilt_pid ) { sleep 1; @@ -293,40 +466,40 @@ if ( not $task1net_pid ) { sleep 2; exit; } -ok( $task1net_pid > 0 ); # Did task1net start ok? +ok( $task1net_pid > 0 ); # Did task1net start ok? sleep .01; open( $contidfd, '>', "/proc/$task1net_pid/audit_containerid" ); $contidfd->autoflush(1); $result = print $contidfd $contid1net; close($contidfd); -ok($result); # Was contid1net written to task1net? +ok($result); # Was contid1net written to task1net? my $task2net_pid = fork(); if ( not $task2net_pid ) { sleep 2; exit; } -ok( $task2net_pid > 0 ); # Did task2net start ok? +ok( $task2net_pid > 0 ); # Did task2net start ok? sleep .01; open( $contidfd, '>', "/proc/$task2net_pid/audit_containerid" ); $contidfd->autoflush(1); $result = print $contidfd $contid2net; close($contidfd); -ok($result); # Was contid2net written to task2net? +ok($result); # Was contid2net written to task2net? # 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 +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 +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? +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" @@ -353,7 +526,7 @@ $result = system( ok( $result, 0 ); # Was an event found? my $contid1net_found = 0; my $contid2net_found = 0; -my $id = ""; +my $id = ""; while ( $line = <$fh_out> ) { @@ -395,12 +568,12 @@ if ( not $taskcap_pid ) { print "syscall SYS_unshare failed with errno:" . $! . "\n"; } sleep 2; - my $taskcapchild_pid = fork(); - if ( not $taskcapchild_pid ) { + my $taskcapc_pid = fork(); + if ( not $taskcapc_pid ) { sleep 2; exit; } - open( my $contidfd, '>', "/proc/$taskcapchild_pid/audit_containerid" ); + open( my $contidfd, '>', "/proc/$taskcapc_pid/audit_containerid" ); $contidfd->autoflush(1); $resultcap = print $contidfd $contidcap; close($contidfd); @@ -446,8 +619,23 @@ if ( defined $ENV{ATS_DEBUG} && $ENV{ATS_DEBUG} == 1 ) { if ( !$contid2_found ) { print "task2_pid=$task2_pid contid2=$contid2\n"; } + if ( !$recsig_found + || !$recsigc_found + || !$recsigc2_found + || !$recsigk_found ) + { + print +"script=$$ tasksig pid=$tasksig_pid contid=$contidsig record=$tasksig_rec\n"; + print +" child pid=$tasksigc_pid contid=$contidsigc record=$tasksigc_rec result=$resultsig \n"; + print +" child2 pid=$tasksigc2_pid contid=$contidsigc2 record=$tasksigc2_rec \n"; + print + " kill pid=$tasksigk_pid contid=$contidsigk record=$tasksigk_rec\n"; + } if ( !$contidfilt_found ) { - print "taskfilt_pid=$taskfilt_pid contidfilt=$contidfilt dir=$tmpdir key=$key\n"; + print +"taskfilt_pid=$taskfilt_pid contidfilt=$contidfilt dir=$tmpdir key=$key\n"; } if ( !$contid1net_found ) { print "mark=$mark id=$id contid1net=$contid1net\n"; diff --git a/tests/netfilter_pkt/test b/tests/netfilter_pkt/test index 33825d8..c2f195d 100755 --- a/tests/netfilter_pkt/test +++ b/tests/netfilter_pkt/test @@ -133,6 +133,9 @@ while ( $line = <$fh_out> ) { { $found[$_] = 1; $fields[$_] += () = $line =~ / [^ =]*=[^ =]*/g; + if ( $line =~ / record=1 / ) { + $fields = 6; + } } else { print $line;