summaryrefslogtreecommitdiffstats
path: root/tests/selinux
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-06-14 12:38:01 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-06-14 16:12:57 +0100
commit81ee155b9d385f73efa8540faea5725701d1ec5d (patch)
tree783dd44f23b22cee68ef9b2a9a323479a1f6070b /tests/selinux
parentabbace68881b0917919913fe71bd738e45f36df5 (diff)
downloadlibguestfs-81ee155b9d385f73efa8540faea5725701d1ec5d.tar.gz
libguestfs-81ee155b9d385f73efa8540faea5725701d1ec5d.tar.xz
libguestfs-81ee155b9d385f73efa8540faea5725701d1ec5d.zip
tests: Add tests for extended attrs and SELinux, direct and via FUSE.
Note that the SELinux + FUSE test is disabled because of: https://bugzilla.redhat.com/show_bug.cgi?id=811217 https://bugzilla.redhat.com/show_bug.cgi?id=812798#c42
Diffstat (limited to 'tests/selinux')
-rw-r--r--tests/selinux/Makefile.am44
-rwxr-xr-xtests/selinux/run-test.pl336
-rwxr-xr-xtests/selinux/test-selinux-direct.sh21
-rwxr-xr-xtests/selinux/test-selinux-fuse.sh21
-rwxr-xr-xtests/selinux/test-xattrs-direct.sh21
-rwxr-xr-xtests/selinux/test-xattrs-fuse.sh21
6 files changed, 464 insertions, 0 deletions
diff --git a/tests/selinux/Makefile.am b/tests/selinux/Makefile.am
new file mode 100644
index 00000000..29ee7fdc
--- /dev/null
+++ b/tests/selinux/Makefile.am
@@ -0,0 +1,44 @@
+# libguestfs
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# Test extended attributes and SELinux labelling, both using the API
+# directly, and over FUSE.
+
+include $(top_srcdir)/subdir-rules.mk
+
+TESTS = \
+ test-xattrs-direct.sh \
+ test-selinux-direct.sh
+
+if HAVE_FUSE
+TESTS += \
+ test-xattrs-fuse.sh \
+ test-selinux-fuse.sh
+endif
+
+random_val := $(shell awk 'BEGIN{srand(); print 1+int(255*rand())}' < /dev/null)
+
+TESTS_ENVIRONMENT = \
+ MALLOC_PERTURB_=$(random_val) \
+ $(top_builddir)/run
+
+EXTRA_DIST = \
+ run-test.pl \
+ test-xattrs-direct.sh \
+ test-xattrs-fuse.sh \
+ test-selinux-direct.sh \
+ test-selinux-fuse.sh
diff --git a/tests/selinux/run-test.pl b/tests/selinux/run-test.pl
new file mode 100755
index 00000000..4a0ccee4
--- /dev/null
+++ b/tests/selinux/run-test.pl
@@ -0,0 +1,336 @@
+#!/usr/bin/perl
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+
+use Sys::Guestfs;
+use Sys::Guestfs::Lib qw(feature_available);
+
+# These are two SELinux labels that we assume everyone is allowed to
+# set under any policy.
+my $label1 = "unconfined_u:object_r:user_tmp_t:s0";
+my $label2 = "unconfined_u:object_r:user_home_t:s0";
+
+my $prog = $0;
+$prog =~ s{.*/}{};
+
+my $errors = 0;
+
+if (@ARGV == 3 && $ARGV[0] eq "--test") {
+ run_fuse_tests ($ARGV[1], $ARGV[2]);
+}
+
+if (@ARGV != 2) {
+ print STDERR "$0: incorrect number of parameters for test\n";
+ exit 1
+}
+
+my $test_type = $ARGV[0];
+die unless $test_type eq "xattrs" || $test_type eq "selinux";
+my $test_via = $ARGV[1];
+die unless $test_via eq "direct" || $test_via eq "fuse";
+
+# SELinux labelling won't work (and can be skipped) if SELinux isn't
+# installed or isn't enabled on the host.
+if ($test_type eq "selinux") {
+ $_ = qx{getenforce 2>&1 ||:};
+ chomp;
+ if ($_ ne "Enforcing" && $_ ne "Permissive") {
+ print "$prog $test_type $test_via: test skipped because SELinux is not enabled.\n";
+ exit
+ }
+}
+
+# Skip FUSE test if the kernel module is not available.
+if ($test_via eq "fuse") {
+ unless (-w "/dev/fuse") {
+ print "$prog $test_type $test_via: test skipped because there is no /dev/fuse.\n";
+ exit
+ }
+}
+
+# For FUSE xattr test, setfattr program is required.
+if ($test_type eq "xattrs" && $test_via eq "fuse") {
+ if (system ("setfattr --help >/dev/null 2>&1") != 0) {
+ print "$prog $test_type $test_via: test skipped because 'setfattr' is not installed.\n";
+ exit
+ }
+}
+
+# For SELinux on FUSE test, chcon program is required.
+if ($test_type eq "selinux" && $test_via eq "fuse") {
+ if (system ("chcon --help >/dev/null 2>&1") != 0) {
+ print "$prog $test_type $test_via: test skipped because 'chcon' is not installed.\n";
+ exit
+ }
+}
+
+# SELinux on FUSE test won't work until SELinux (or FUSE) is fixed.
+# See:
+# https://bugzilla.redhat.com/show_bug.cgi?id=811217
+# https://bugzilla.redhat.com/show_bug.cgi?id=812798#c42
+if ($test_type eq "selinux" && $test_via eq "fuse") {
+ print "$prog $test_type $test_via: test skipped because SELinux and FUSE\n";
+ print "don't work well together:\n";
+ print "https://bugzilla.redhat.com/show_bug.cgi?id=811217\n";
+ print "https://bugzilla.redhat.com/show_bug.cgi?id=812798#c42\n";
+ exit;
+}
+
+# Create a filesystem that could support xattrs and SELinux labels.
+my $g = Sys::Guestfs->new ();
+
+#$g->set_selinux (1) if $test_type eq "selinux";
+
+my $testimg = "test.img";
+open FILE, ">$testimg" or die "$testimg: $!";
+truncate FILE, 256*1024*1024 or die "$testimg: truncate: $!";
+close FILE or die "$testimg: $!";
+
+$g->add_drive_opts ($testimg, format => "raw");
+$g->launch ();
+
+unless (feature_available ($g, "linuxxattrs")) {
+ print "$prog $test_type $test_via: test skipped because 'linuxxattrs' feature not available.\n";
+ $g->close ();
+ unlink $testimg;
+ exit 0
+}
+
+$g->part_disk ("/dev/sda", "mbr");
+$g->mkfs ("ext4", "/dev/sda1");
+
+$g->mount_options ("user_xattr", "/dev/sda1", "/");
+
+# Run the test.
+if ($test_via eq "direct") {
+ if ($test_type eq "xattrs") {
+ xattrs_direct ();
+ } elsif ($test_type eq "selinux") {
+ selinux_direct ();
+ } else {
+ die "unknown test type: $test_type";
+ }
+} else {
+ # Make a local mountpoint and mount it.
+ mkdir "mp" or die "mkdir: mp: $!";
+ $g->mount_local ("mp");
+
+ # Run the test in another process.
+ my $pid = fork ();
+ die "fork: $!" unless defined $pid;
+ if ($pid == 0) {
+ exec ("./run-test.pl", "--test", "mp", $test_type);
+ die "run-test.pl: exec failed: $!\n";
+ }
+
+ $g->mount_local_run ();
+
+ waitpid ($pid, 0);
+ $errors++ if $?;
+
+ rmdir "mp" or die "rmdir: mp: $!";
+}
+
+# Finish up.
+$g->close ();
+unlink $testimg or die "$testimg: $!";
+
+exit ($errors == 0 ? 0 : 1);
+
+# Run the FUSE tests in a subprocess.
+sub run_fuse_tests
+{
+ my $mpdir = shift;
+ my $test_type = shift; # "xattrs" or "selinux"
+
+ if ($test_type eq "xattrs") {
+ xattrs_fuse ($mpdir);
+ } elsif ($test_type eq "selinux") {
+ selinux_fuse ($mpdir);
+ } else {
+ die "unknown test type: $test_type";
+ }
+
+ # Unmount the test directory.
+ unmount ($mpdir);
+
+ exit ($errors == 0 ? 0 : 1);
+}
+
+# Unmount the FUSE directory. We may need to retry this a few times.
+sub unmount
+{
+ my $mpdir = shift;
+ my $retries = 5;
+
+ while ($retries > 0) {
+ if (system ("fusermount", "-u", $mpdir) == 0) {
+ last;
+ }
+ sleep 1;
+ $retries--;
+ }
+
+ if ($retries == 0) {
+ die "failed to unmount FUSE directory\n";
+ }
+}
+
+# Test extended attributes, using the libguestfs API directly.
+sub xattrs_direct
+{
+ $g->touch ("/test");
+ $g->setxattr ("user.test", "test content", 12, "/test");
+ my $attrval = $g->getxattr ("/test", "user.test");
+ if ($attrval ne "test content") {
+ print STDERR "$prog: failed to set or get xattr using API.\n";
+ $errors++;
+ }
+ my @xattrs = $g->getxattrs ("/test");
+ my $found = 0;
+ foreach (@xattrs) {
+ if ($_->{attrname} eq "user.test" && $_->{attrval} eq "test content") {
+ $found++;
+ }
+ }
+ if ($found != 1) {
+ print STDERR "$prog: user.test xattr not returned by getxattrs.\n";
+ $errors++;
+ }
+ $g->removexattr ("user.test", "/test");
+ @xattrs = $g->getxattrs ("/test");
+ $found = 0;
+ foreach (@xattrs) {
+ if ($_->{attrname} eq "user.test") {
+ $found++;
+ }
+ }
+ if ($found != 0) {
+ print STDERR "$prog: user.test xattr not removed by removexattr.\n";
+ $errors++;
+ }
+}
+
+# Test extended attributes, over FUSE.
+sub xattrs_fuse
+{
+ my $mpdir = shift;
+
+ open FILE, "> $mpdir/test" or die "$mpdir/test: $!";
+ print FILE "test\n";
+ close FILE;
+
+ system ("setfattr", "-n", "user.test", "-v", "test content", "$mpdir/test")
+ == 0 or die "setfattr: $!";
+ my @xattrs = qx{ getfattr -m '.*' -d $mpdir/test };
+ my $found = 0;
+ foreach (@xattrs) {
+ if (m/^user.test="test content"$/) {
+ $found++;
+ }
+ }
+ if ($found != 1) {
+ print STDERR "$prog: user.test xattr not returned by getfattr.\n";
+ $errors++;
+ }
+
+ system ("setfattr", "-x", "user.test", "$mpdir/test")
+ == 0 or die "setfattr: $!";
+ @xattrs = qx{ getfattr -m '.*' -d $mpdir/test };
+ $found = 0;
+ foreach (@xattrs) {
+ if (m/^user.test=$/) {
+ $found++;
+ }
+ }
+ if ($found != 0) {
+ print STDERR "$prog: user.test xattr not removed by setfattr -x.\n";
+ $errors++;
+ }
+}
+
+# Test SELinux labels, using the libguestfs API directly.
+sub selinux_direct
+{
+ $g->touch ("/test");
+
+ $g->setxattr ("security.selinux", $label1, length $label1, "/test");
+ my $attrval = $g->getxattr ("/test", "security.selinux");
+ if ($attrval ne $label1) {
+ print STDERR "$prog: failed to set or get selinux label '$label1' using API.\n";
+ $errors++;
+ }
+
+ $g->setxattr ("security.selinux", $label2, length $label2, "/test");
+ $attrval = $g->getxattr ("/test", "security.selinux");
+ if ($attrval ne $label2) {
+ print STDERR "$prog: failed to set or get selinux label '$label2' using API.\n";
+ $errors++;
+ }
+
+ my @xattrs = $g->getxattrs ("/test");
+ my $found = 0;
+ foreach (@xattrs) {
+ if ($_->{attrname} eq "security.selinux" && $_->{attrval} eq $label2) {
+ $found++;
+ }
+ }
+ if ($found != 1) {
+ print STDERR "$prog: security.selinux xattr not returned by getxattrs.\n";
+ $errors++;
+ }
+ $g->removexattr ("security.selinux", "/test");
+ @xattrs = $g->getxattrs ("/test");
+ $found = 0;
+ foreach (@xattrs) {
+ if ($_->{attrname} eq "security.selinux") {
+ $found++;
+ }
+ }
+ if ($found != 0) {
+ print STDERR "$prog: security.selinux xattr not removed by removexattr.\n";
+ $errors++;
+ }
+}
+
+# Test SELinux labels, over FUSE.
+sub selinux_fuse
+{
+ my $mpdir = shift;
+
+ open FILE, "> $mpdir/test" or die "$mpdir/test: $!";
+ print FILE "test\n";
+ close FILE;
+
+ system ("chcon", $label1, "$mpdir/test") == 0 or die "chcon: $!";
+ $_ = qx{ ls -Z $mpdir/test | awk '{print $4}' };
+ chomp;
+ if ($_ ne $label1) {
+ print STDERR "$prog: failed to set of get selinux label '$label1' using FUSE.\n";
+ $errors++;
+ }
+
+ system ("chcon", $label2, "$mpdir/test") == 0 or die "chcon: $!";
+ $_ = qx{ ls -Z $mpdir/test | awk '{print $4}' };
+ chomp;
+ if ($_ ne $label2) {
+ print STDERR "$prog: failed to set of get selinux label '$label2' using FUSE.\n";
+ $errors++;
+ }
+}
diff --git a/tests/selinux/test-selinux-direct.sh b/tests/selinux/test-selinux-direct.sh
new file mode 100755
index 00000000..caf39f20
--- /dev/null
+++ b/tests/selinux/test-selinux-direct.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -
+# libguestfs
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+rm -rf test.img mp
+
+exec ./run-test.pl selinux direct
diff --git a/tests/selinux/test-selinux-fuse.sh b/tests/selinux/test-selinux-fuse.sh
new file mode 100755
index 00000000..ab7b0ede
--- /dev/null
+++ b/tests/selinux/test-selinux-fuse.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -
+# libguestfs
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+rm -rf test.img mp
+
+exec ./run-test.pl selinux fuse
diff --git a/tests/selinux/test-xattrs-direct.sh b/tests/selinux/test-xattrs-direct.sh
new file mode 100755
index 00000000..354a496a
--- /dev/null
+++ b/tests/selinux/test-xattrs-direct.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -
+# libguestfs
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+rm -rf test.img mp
+
+exec ./run-test.pl xattrs direct
diff --git a/tests/selinux/test-xattrs-fuse.sh b/tests/selinux/test-xattrs-fuse.sh
new file mode 100755
index 00000000..87652612
--- /dev/null
+++ b/tests/selinux/test-xattrs-fuse.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -
+# libguestfs
+# Copyright (C) 2012 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+rm -rf test.img mp
+
+exec ./run-test.pl xattrs fuse