[apparmor] [PATCH 2/4] tests: Improve mount rule tests
Tyler Hicks
tyhicks at canonical.com
Wed Mar 26 17:00:46 UTC 2014
From: John Johansen <john.johansen at canonical.com>
The mount.sh regression test script was not testing with actual AppArmor
mount rules. This patch improves mkprofile.pl by adding the ability to
generate mount rules and adds tests to mount.sh that verify mount
mediation is working properly.
Signed-off-by: John Johansen <john.johansen at canonical.com>
[tyhicks: Fixed a couple typos and added fstype tests]
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
tests/regression/apparmor/mkprofile.pl | 78 +++++++++++++++++++++++
tests/regression/apparmor/mount.sh | 113 ++++++++++++++++++++++++++++-----
2 files changed, 175 insertions(+), 16 deletions(-)
diff --git a/tests/regression/apparmor/mkprofile.pl b/tests/regression/apparmor/mkprofile.pl
index 1c1fc6b..e3f1598 100755
--- a/tests/regression/apparmor/mkprofile.pl
+++ b/tests/regression/apparmor/mkprofile.pl
@@ -174,6 +174,78 @@ sub gen_cap($) {
}
}
+sub gen_mount($) {
+ my $rule = shift;
+ my @rules = split (/:/, $rule);
+ if (@rules == 2) {
+ if ($rules[1] =~ /^ALL$/) {
+ push (@{$output_rules{$hat}}, " mount,\n");
+ } else {
+ push (@{$output_rules{$hat}}, " mount $rules[1],\n");
+ }
+ } elsif (@rules == 3) {
+ push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2],\n");
+ } elsif (@rules == 4) {
+ push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3],\n");
+ } elsif (@rules == 5) {
+ push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4],\n");
+ } elsif (@rules == 6) {
+ push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n");
+ } elsif (@rules == 7) {
+ push (@{$output_rules{$hat}}, " mount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n");
+ } else {
+ (!$nowarn) && print STDERR "Warning: invalid mount description '$rule', ignored\n";
+ }
+}
+
+sub gen_remount($) {
+ my $rule = shift;
+ my @rules = split (/:/, $rule);
+ if (@rules == 2) {
+ if ($rules[1] =~ /^ALL$/) {
+ push (@{$output_rules{$hat}}, " remount,\n");
+ } else {
+ push (@{$output_rules{$hat}}, " remount $rules[1],\n");
+ }
+ } elsif (@rules == 3) {
+ push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2],\n");
+ } elsif (@rules == 4) {
+ push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3],\n");
+ } elsif (@rules == 5) {
+ push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4],\n");
+ } elsif (@rules == 6) {
+ push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n");
+ } elsif (@rules == 7) {
+ push (@{$output_rules{$hat}}, " remount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n");
+ } else {
+ (!$nowarn) && print STDERR "Warning: invalid remount description '$rule', ignored\n";
+ }
+}
+
+sub gen_umount($) {
+ my $rule = shift;
+ my @rules = split (/:/, $rule);
+ if (@rules == 2) {
+ if ($rules[1] =~ /^ALL$/) {
+ push (@{$output_rules{$hat}}, " umount,\n");
+ } else {
+ push (@{$output_rules{$hat}}, " umount $rules[1],\n");
+ }
+ } elsif (@rules == 3) {
+ push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2],\n");
+ } elsif (@rules == 4) {
+ push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3],\n");
+ } elsif (@rules == 5) {
+ push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4],\n");
+ } elsif (@rules == 6) {
+ push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5],\n");
+ } elsif (@rules == 7) {
+ push (@{$output_rules{$hat}}, " umount $rules[1] $rules[2] $rules[3] $rules[4] $rules[5] $rules[6],\n");
+ } else {
+ (!$nowarn) && print STDERR "Warning: invalid umount description '$rule', ignored\n";
+ }
+}
+
sub gen_file($) {
my $rule = shift;
my @rules = split (/:/, $rule);
@@ -260,6 +332,12 @@ sub gen_from_args() {
gen_network($rule);
} elsif ($rule =~ /^cap:/) {
gen_cap($rule);
+ } elsif ($rule =~ /^mount:/) {
+ gen_mount($rule);
+ } elsif ($rule =~ /^remount:/) {
+ gen_remount($rule);
+ } elsif ($rule =~ /^umount:/) {
+ gen_umount($rule);
} elsif ($rule =~ /^flag:/) {
gen_flag($rule);
} elsif ($rule =~ /^hat:/) {
diff --git a/tests/regression/apparmor/mount.sh b/tests/regression/apparmor/mount.sh
index 5cfa3fe..dc46601 100755
--- a/tests/regression/apparmor/mount.sh
+++ b/tests/regression/apparmor/mount.sh
@@ -28,11 +28,29 @@ bin=$pwd
mount_file=$tmpdir/mountfile
mount_point=$tmpdir/mountpoint
+mount_bad=$tmpdir/mountbad
loop_device="unset"
+fstype="ext2"
+
+setup_mnt() {
+ /bin/mount -t${fstype} ${loop_device} ${mount_point}
+# /bin/mount -t${fstype} ${loop_device} ${mount_bad}
+}
+remove_mnt() {
+ mountpoint -q "${mount_point}"
+ if [ $? -eq 0 ] ; then
+ /bin/umount -t${fstype} ${mount_point}
+ fi
+ mountpoint -q "${mount_bad}"
+ if [ $? -eq 0 ] ; then
+ /bin/umount -t${fstype} ${mount_bad}
+ fi
+}
dd if=/dev/zero of=${mount_file} bs=1024 count=512 2> /dev/null
-/sbin/mkfs -text2 -F ${mount_file} > /dev/null 2> /dev/null
+/sbin/mkfs -t${fstype} -F ${mount_file} > /dev/null 2> /dev/null
/bin/mkdir ${mount_point}
+/bin/mkdir ${mount_bad}
# in a modular udev world, the devices won't exist until the loopback
# module is loaded.
@@ -56,32 +74,95 @@ then
fatalerror 'Unable to find a free loop device'
fi
-# TEST 1. Make sure can mount and umount unconfined
+# TEST 1. Make sure can mount and umount unconfined
runchecktest "MOUNT (unconfined)" pass mount ${loop_device} ${mount_point}
-runchecktest "UMOUNT (unconfined)" pass umount ${loop_device} ${mount_point}
+remove_mnt
-# TEST A2. confine MOUNT
+setup_mnt
+runchecktest "UMOUNT (unconfined)" pass umount ${loop_device} ${mount_point}
+remove_mnt
+# TEST A2. confine MOUNT no perms
genprofile
-runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point}
+runchecktest "MOUNT (confined no perm)" fail mount ${loop_device} ${mount_point}
+remove_mnt
-# TEST A3. confine MOUNT - cap sys_admin is not sufficient to mount
-genprofile capability:sys_admin
-runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point}
+setup_mnt
+runchecktest "UMOUNT (confined no perm)" fail umount ${loop_device} ${mount_point}
+remove_mnt
-/bin/umount -text2 ${mount_point}
-# TEST A4. confine UMOUNT
+if [ "$(have_features mount)" != "true" ] ; then
+ genprofile capability:sys_admin
+ runchecktest "MOUNT (confined cap)" pass mount ${loop_device} ${mount_point}
+ remove_mnt
-/bin/mount -text2 ${loop_device} ${mount_point}
+ setup_mnt
+ runchecktest "UMOUNT (confined cap)" pass umount ${loop_device} ${mount_point}
+ remove_mnt
+else
+ echo " using mount rules ..."
-genprofile
-runchecktest "UMOUNT (confined)" fail umount ${loop_device} ${mount_point}
+ genprofile capability:sys_admin
+ runchecktest "MOUNT (confined cap)" fail mount ${loop_device} ${mount_point}
+ remove_mnt
+
+ setup_mnt
+ runchecktest "UMOUNT (confined cap)" fail umount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile mount:ALL
+ runchecktest "MOUNT (confined mount:ALL)" fail mount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile "mount:-> ${mount_point}/"
+ runchecktest "MOUNT (confined bad mntpnt mount -> mntpnt)" fail mount ${loop_device} ${mount_bad}
+ remove_mnt
+
+ runchecktest "MOUNT (confined mount -> mntpnt)" fail mount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+
+ genprofile umount:ALL
+ setup_mnt
+ runchecktest "UMOUNT (confined umount:ALL)" fail umount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile mount:ALL cap:sys_admin
+ runchecktest "MOUNT (confined cap mount:ALL)" pass mount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile cap:sys_admin "mount:-> ${mount_point}/"
+ runchecktest "MOUNT (confined bad mntpnt cap mount -> mntpnt)" fail mount ${loop_device} ${mount_bad}
+ remove_mnt
+
+ runchecktest "MOUNT (confined cap mount -> mntpnt)" pass mount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile cap:sys_admin "mount:fstype=${fstype}XXX"
+ runchecktest "MOUNT (confined cap mount bad fstype)" fail mount ${loop_device} ${mount_point}
+ remove_mnt
+
+ genprofile cap:sys_admin "mount:fstype=${fstype}"
+ runchecktest "MOUNT (confined cap mount fstype)" pass mount ${loop_device} ${mount_point}
+ remove_mnt
+
+
+ genprofile cap:sys_admin umount:ALL
+ setup_mnt
+ runchecktest "UMOUNT (confined cap umount:ALL)" pass umount ${loop_device} ${mount_point}
+ remove_mnt
+
+fi
-# TEST A4. confine UMOUNT - cap sys_admin allows unmount
-genprofile capability:sys_admin
-runchecktest "UMOUNT (confined)" pass umount ${loop_device} ${mount_point}
+#need tests for move mount, remount, bind mount, pivot root, chroot
# cleanup, umount file
/bin/umount ${loop_device} > /dev/null 2> /dev/null || /sbin/losetup -d ${loop_device} > /dev/null 2> /dev/null
--
1.9.1
More information about the AppArmor
mailing list