[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 15/17] dm restrict audit: Provide auditing script



ts-depriv-audit-qemu knows how to create a domain paused, and audit
its fds.  It uses
  * osstest-depriv-fd-collector, an on-test-host helper script
  * fishdescriptor, a new utility program in chiark-scripts
  * depriv-fd-checker, a new test program in xen.git

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 overlay/usr/local/bin/osstest-depriv-fd-collector |  94 +++++++++++++
 ts-depriv-audit-qemu                              | 154 ++++++++++++++++++++++
 2 files changed, 248 insertions(+)
 create mode 100755 overlay/usr/local/bin/osstest-depriv-fd-collector
 create mode 100755 ts-depriv-audit-qemu

diff --git a/overlay/usr/local/bin/osstest-depriv-fd-collector 
b/overlay/usr/local/bin/osstest-depriv-fd-collector
new file mode 100755
index 0000000..b7444f8
--- /dev/null
+++ b/overlay/usr/local/bin/osstest-depriv-fd-collector
@@ -0,0 +1,94 @@
+#!/usr/bin/perl -w
+#
+# usage: osstest-depriv-fd-collector <pid>
+#
+# audits that <pid> has only depriv fds, eg for a depriv qemu
+#
+# output is series of lines
+#    <class> pass|fail <fd> <info>  repeated for each fd
+#    [<pid>] <fd> sockinfo...       as from fishdescriptor
+#    generic unknown <fd> </proc link target>
+#
+# fishdescriptor on every fd in <pid>
+#    check what kind of fd it is
+#
+# classes are
+#   generic
+#      (handled here)
+#   appendonly
+#   readonly
+#   privcmd
+#   gntdev
+#   evtchn
+#      (passed to fishdescriptor and depriv-fd-checker)
+
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2018 Citrix Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use strict;
+
+die unless @ARGV==2;
+our ($pid,$checker) = @ARGV;
+die unless $pid =~ m{^\d+$};
+
+our @fdchecks;
+our @fdsockinfos;
+
+open F, "find /proc/$pid/fd/* -printf '%f %l\\n' |" or die $!;
+while (<F>) {
+    chomp;
+    die "$_ ?" unless s/^(\d+) //;
+    my $fd = $1;
+    if (m{^/dev/null$} ||
+       m{^pipe:} ||
+        m{^anon_inode:\[(?:signalfd|eventfd|eventpoll)\]$}) {
+       print "generic pass $fd $_\n" or die $!;
+    } elsif (m{^/var/log/xen/qemu-dm-.*\.log$}) {
+       push @fdchecks, [ $fd, 'appendonly', $_ ];
+    } elsif (m{^/dev/urandom$} ||
+            m{^/root/.*.iso}) {
+       push @fdchecks, [ $fd, 'readonly', $_ ];
+    } elsif (m{^/dev/xen/(privcmd|gntdev|evtchn)$}) {
+       push @fdchecks, [ $fd, $1, $_ ];
+    } elsif (m{^/dev/net/tun$}) {
+       push @fdchecks, [ $fd, 'tun', $_ ];
+    } elsif (m{^socket:}) {
+       push @fdsockinfos, $fd;
+    } else {
+       print "generic unknown $fd $_\n" or die $!;
+    }
+}
+close F or die "$? $!";
+
+my @fish = (qw(fishdescriptor), $pid);
+my @chk = $checker;
+
+foreach my $fd (@fdsockinfos) {
+    push @fish, $fd, qw(sockinfo);
+}
+
+foreach my $fdi (@fdchecks) {
+    my ($fd, $class, $rhs) = @$fdi;
+    my $fish_fd = $fd + 100;
+    push @fish, "$fish_fd=$fd";
+    push @chk, $class, $fish_fd, "$fd=$rhs";
+}
+
+my @cmd = (@fish, qw(exec), @chk);
+
+print STDERR "$0 running @cmd\n";
+
+exec @cmd or die $!;
diff --git a/ts-depriv-audit-qemu b/ts-depriv-audit-qemu
new file mode 100755
index 0000000..2405b69
--- /dev/null
+++ b/ts-depriv-audit-qemu
@@ -0,0 +1,154 @@
+#!/usr/bin/perl -w
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2018 Citrix Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use strict qw(vars);
+use DBI;
+BEGIN { unshift @INC, qw(.); }
+use Osstest;
+use Osstest::TestSupport;
+
+use Data::Dumper;
+$Data::Dumper::Useqq = 1;
+
+tsreadconfig();
+
+our $mode = shift @ARGV;
+our $modesubproc = ${*::}{"mode_$mode"};
+die "unknown mode $mode ?" unless $modesubproc;
+
+our ($ho,$gho) = ts_get_host_guest(@ARGV);
+
+
+our $data_re;
+our $fish_output;
+
+sub compile_data_re () {
+    $data_re = join '|', map { chomp; qr{$_}; } <DATA>;
+}      
+
+sub fish_guest () {
+    $fish_output = target_cmd_output_root($ho, <<END.<<'END');
+        set -ex
+        domid=\$(xl domid '$gho->{Name}')
+END
+        qpid=$(xenstore-read /local/domain/$domid/image/device-model-pid)
+        uid=$(id -u xen-qemuuser-range-base)
+        uid=$(( $uid + $domid ))
+        test -d /run/user || mkdir -m 2755 /run/user
+        if mkdir -m 2700 /run/user/$uid; then
+            chown $uid:root /run/user/$uid
+        fi
+        osstest-depriv-fd-collector $qpid \
+        /usr/local/lib/xen/bin/depriv-fd-checker
+END
+    stashfilecontents($fish_output,"fish-info-paused.txt");
+}
+
+sub packages () {
+    target_install_packages_norec($ho, qw(python3 gdb libsocket-msghdr-perl));
+    # ^ fishdescriptor needs those
+}
+
+#----- actual auditing core -----
+
+our %classes;
+our $disk_dev;
+
+sub audit_prep () {
+    $disk_dev = $gho->{Diskimg} || $gho->{Lvdev};
+    $disk_dev = target_cmd_output_root($ho, "realpath $disk_dev");
+    logm("real guest disk device: $disk_dev");
+    
+    logm("prep complete, starting audit...");
+    foreach my $cl (qw(privcmd gntdev evtchn other xenstore)) {
+       $classes{$cl} = '';
+       substep_start("/$cl");
+    }
+}
+
+sub fd ($$$) {
+    my ($class,$passfail,$info) = @_;
+    die "$class ?" unless defined $classes{$class};
+    $classes{$class} ||= 'pass';
+    $classes{$class} = $passfail unless $passfail eq 'pass';
+    printf "%-10s %-7s %-20s | %s\n", $class, $passfail, $info, $_ or die $!;
+}
+
+sub audit_fish () {
+    foreach $_ (split /\n/, $fish_output) {
+       if (m{^(privcmd|gntdev|evtchn) (pass|fail) }) {
+           fd($1,$2, 'checked xen');
+       } elsif (m{^\w+ checking }) {
+           printf "%-39s | %s\n", '', $_;
+       } elsif (m{^(\w+) (pass|fail) }) {
+           fd('other',$2, "checked $1");
+       } elsif (m{^\[\d+\] \d+ 
sockinfo\s+AF_UNIX\tb''\t'/var/run/xenstored/socket'}) {
+           fd('xenstore','fail','xenstore socket');
+       } elsif (m{^generic unknown \d+ \Q$disk_dev\E$}) {
+           fd('other','pass','disk device');
+       } elsif (m{$data_re}) {
+           fd('other','pass','pattern (DATA)');
+       } elsif (m{^\w+ \w+ }) {
+           fd('other','fail',"confusing");
+       } else {
+           local $Data::Dumper::Terse = 1;
+           $_ = Dumper($_);
+           chomp;
+           fd('other','fail','unknown');
+       }
+    }
+
+    foreach my $cl (sort keys %classes) {
+       substep_finish("/$cl", $classes{$cl} || 'pass');
+       # (if there are no fds of this class, maybe they were all closed)
+    }
+    logm("audit complete...");
+}
+
+#----- administrivia, main program, etc. -----
+
+sub mode_create () {
+    packages();
+    guest_create_paused($gho);
+    audit_prep();
+    fish_guest();
+    audit_fish();
+    guest_unpause($gho);
+    guest_await($gho, target_var($gho,'boot_timeout'));
+    guest_check_up($gho);
+}
+
+sub mode_ispaused () {
+    packages();
+    audit_prep();
+    fish_guest();
+    audit_fish();
+}
+
+compile_data_re();
+$modesubproc->();
+
+logm("audited operation complete.");
+
+#----- tolerate these -----
+
+__DATA__
+^generic unknown \d+ /var/log/xen/osstest-serial-.*\.log$
+^generic unknown \d+ /root/\d+\..*\.serial\.in$
+^\[\d+\] \d+ sockinfo\s+AF_UNIX\t+'/var/run/xen/qmp-(?:libxl|libxenstat)-\d+'\t
+^\[\d+\] \d+ sockinfo\s+AF_INET\t+\('[0-9:.]+', 59\d\d\)\t
+^tun maybe \d+ vif\d+\.0-emu \d+=
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.