[apparmor] [PATCH v3 6/7] tests: Add abstract socket tests

Tyler Hicks tyhicks at canonical.com
Tue Sep 23 00:09:16 UTC 2014


Tests abstract UNIX domain sockets with various combinations of implied
permissions, explicit permissions, and conditionals. It also tests with
bad permissions and conditionals.

The new file unix_socket.inc includes a generic set of tests that can be
reused by another test script in order to test unnamed AF_UNIX socket
mediation. The do_test() function is conditionalized in a way that it
can test confined servers and confined clients depending on the
arguments passed in.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---

* Changes since v2:
  - Added unix_socket_abstract to the TESTS variable in the Makefile
  - Combined test_server() and test_client() into a single do_test() function
    + Both functions were doing the same tests and policy variations but one
      had a confined server and unconfined client while the other had a
      confined server and client
  - Adjusted tests to account for "pre-bind" and "post-bind" permissions.
    Pre-bind permissions can't be specified in rules that contain local addr
    conditionals as the kernel will fail the local address match.
  - Fixed NAME and DESCRIPTION metadata in unix_socket_abstract.sh header
  - Adjusted unix_socket_abstract.sh to call do_test()

 tests/regression/apparmor/Makefile                |   1 +
 tests/regression/apparmor/unix_socket.inc         | 135 ++++++++++++++++++++++
 tests/regression/apparmor/unix_socket_abstract.sh | 121 +++++++++++++++++++
 3 files changed, 257 insertions(+)
 create mode 100755 tests/regression/apparmor/unix_socket.inc
 create mode 100755 tests/regression/apparmor/unix_socket_abstract.sh

diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile
index 2ef8aca..bacd375 100644
--- a/tests/regression/apparmor/Makefile
+++ b/tests/regression/apparmor/Makefile
@@ -184,6 +184,7 @@ TESTS=access \
       tcp \
       unix_fd_server \
       unix_socket_pathname \
+      unix_socket_abstract \
       unlink\
       xattrs\
       longpath
diff --git a/tests/regression/apparmor/unix_socket.inc b/tests/regression/apparmor/unix_socket.inc
new file mode 100755
index 0000000..e00ee50
--- /dev/null
+++ b/tests/regression/apparmor/unix_socket.inc
@@ -0,0 +1,135 @@
+# Copyright (C) 2014 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License published by the Free Software Foundation.
+#
+# 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, contact Canonical Ltd.
+
+client=$bin/unix_socket_client
+message=4a0c83d87aaa7afa2baab5df3ee4df630f0046d5bfb7a3080c550b721f401b3b\
+8a738e1435a3b77aa6482a70fb51c44f20007221b85541b0184de66344d46a4c
+
+do_test()
+{
+	local addr_type="$1" # abstract or unnamed
+	local test_prog="$2" # server or client
+	local l_u_access="$3" # optional local unbound perms
+	local l_b_access="$4" # local bound perms
+	local type="$5" # stream, dgram, or seqpacket
+	local addr="$6" # optional socket address
+	local p_access="$7" # peer perms
+	local p_label="$8" # peer socket label
+	local p_addr="$9" # optional peer socket address
+	local bad_type="${10}"
+	local bad_addr="${11}" # optional
+	local bad_p_label="${12}"
+	local bad_p_addr="${13}" # optional
+
+	local desc="AF_UNIX $addr_type socket ($type);"
+	local l_access # combind local perms: local bound and local unbound
+	local c_access # combined perms: local bound, local unbound, and peer
+	local access # used as an iterator
+	local u_rule # rule for pre-bind accesses
+	local u_type_rule # rule for pre-bind accesses with a type conditional
+	local genprof="genprofile"
+	local args
+
+	if [ "$test_prog" == "server" ]; then
+		genprof+=" $client:Ux"
+		args="$addr $type $message $client"
+	elif [ "$test_prog" == "client" ]; then
+		genprof+=" unix:ALL $client:px -- image=$client"
+		args="$p_addr $type $message $client"
+	fi
+
+	l_access="$l_b_access"
+	if [ -n "$l_u_access" ]; then
+		l_access="${l_u_access},${l_access}"
+		c_access="${l_u_access},${c_access}"
+
+		u_rule="unix:($l_u_access)"
+		u_type_rule="${u_rule}:type=$type"
+	fi
+	c_access="${l_access},${p_access}"
+
+	runchecktest "$desc unconfined $test_prog" pass $args
+
+	desc+=" confined $test_prog"
+
+	$genprof "unix:ALL"
+	runchecktest "$desc (implicit perms)" pass $args
+
+	$genprof "unix:($c_access)"
+	runchecktest "$desc (explicit perms)" pass $args
+
+	$genprof "unix:($c_access):type=$type"
+	runchecktest "$desc (type)" pass $args
+
+	if [ -n "$addr" ]; then
+		$genprof $u_rule "unix:(${l_b_access},${p_access}):addr=$addr"
+		runchecktest "$desc (addr)" pass $args
+	fi
+
+	$genprof "unix:($l_access)" "unix::peer=(label=$p_label)"
+	runchecktest "$desc (peer label w/ implicit perms)" pass $args
+
+	$genprof "unix:($l_access)" "unix:($p_access):peer=(label=$p_label)"
+	runchecktest "$desc (peer label w/ explicit perms)" pass $args
+
+	if [ -n "$p_addr" ]; then
+		$genprof "unix:($l_access)" "unix:($p_access):peer=(addr=$p_addr)"
+		runchecktest "$desc (peer addr)" pass $args
+
+		$genprof "unix:($l_access)" "unix:($p_access):peer=(label=$p_label addr=$p_addr)"
+		runchecktest "$desc (peer label, peer addr)" pass $args
+
+		$genprof "unix:($l_access):type=$type" "unix:($p_access):type=$type:peer=(label=$p_label addr=$p_addr)"
+		runchecktest "$desc (type, peer label, peer addr)" pass $args
+	fi
+
+	if [ -n "$addr" ]; then
+		$genprof $u_type_rule "unix:($l_b_access):type=$type:addr=$addr" "unix:($p_access):type=$type:addr=$addr"
+		runchecktest "$desc (type, addr)" pass $args
+
+		$genprof $u_type_rule "unix:($l_b_access):type=$type:addr=$addr" "unix:($p_access):type=$type:addr=$addr:peer=(label=$p_label)"
+		runchecktest "$desc (type, addr, peer label)" pass $args
+	fi
+
+	if [ -n "$addr" -a -n "$p_addr" ]; then
+		$genprof $u_type_rule "unix:($l_b_access):type=$type:addr=$addr" "unix:($p_access):type=$type:addr=$addr:peer=(label=$p_label addr=$p_addr)"
+		runchecktest "$desc (type, addr, peer label, peer addr)" pass $args
+	fi
+
+	$genprof
+	runchecktest "$desc (no unix rule)" fail $args
+
+	for access in ${c_access//,/ }; do
+		$genprof "unix:(${c_access//$access/})"
+		runchecktest "$desc (missing perm: $access)" fail $args
+	done
+
+	$genprof "unix:($c_access):type=$bad_type"
+	runchecktest "$desc (bad type)" fail $args
+
+	if [ -n "$bad_addr" ]; then
+		$genprof $u_rule "unix:(${l_b_access},${p_access}):addr=$bad_addr"
+		runchecktest "$desc (bad addr)" fail $args
+	fi
+
+	$genprof "unix:($l_access)" "unix:($p_access):peer=(label=$bad_p_label)"
+	runchecktest "$desc (bad peer label)" fail $args
+
+	if [ -n "$bad_p_addr" ]; then
+		$genprof "unix:($l_access)" "unix:($p_access):peer=(addr=$bad_p_addr)"
+		runchecktest "$desc (bad peer addr)" fail $args
+	fi
+
+	removeprofile
+}
diff --git a/tests/regression/apparmor/unix_socket_abstract.sh b/tests/regression/apparmor/unix_socket_abstract.sh
new file mode 100755
index 0000000..7c14f3e
--- /dev/null
+++ b/tests/regression/apparmor/unix_socket_abstract.sh
@@ -0,0 +1,121 @@
+#! /bin/bash
+#
+# Copyright (C) 2014 Canonical, Ltd.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of version 2 of the GNU General Public
+# License published by the Free Software Foundation.
+#
+# 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, contact Canonical Ltd.
+
+#=NAME unix_socket_abstract
+#=DESCRIPTION
+# This tests access to abstract unix domain sockets. The server opens a socket,
+# forks a client with it's own profile, sends a message to the client over the
+# socket, and sees what happens.
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+bin=$pwd
+
+. $bin/prologue.inc
+. $bin/unix_socket.inc
+requires_features policy/versions/v7
+requires_features network/af_unix
+
+settest unix_socket
+
+addr=@aa_sock
+client_addr=${addr}.client
+
+# Test abstract stream server and client
+do_test "abstract" \
+	"server" \
+	"create,setopt" \
+	"bind,listen,getopt,shutdown" \
+	stream \
+	"$addr" \
+	"accept,read,write" \
+	"unconfined" \
+	"" \
+	dgram \
+	"${addr}XXX" \
+	"XXX" \
+	""
+do_test "abstract" \
+	"client" \
+	"" \
+	"create,getopt,setopt,getattr" \
+	stream \
+	"" \
+	"connect,write,read" \
+	"$test" \
+	"$addr" \
+	seqpacket \
+	"" \
+	"${test}XXX" \
+	"${addr}XXX"
+
+# Test abstract dgram server and client
+do_test "abstract" \
+	"server" \
+	"create,setopt" \
+	"bind,getopt,shutdown" \
+	dgram \
+	"$addr" \
+	"read,write" \
+	"unconfined" \
+	"$client_addr" \
+	seqpacket \
+	"${addr}XXX" \
+	"XXX" \
+	"${client_addr}XXX"
+do_test "abstract" \
+	"client" \
+	"create,setopt,getattr" \
+	"bind,getopt" \
+	dgram \
+	"$client_addr" \
+	"write,read" \
+	"$test" \
+	"$addr" \
+	stream \
+	"${client_addr}XXX" \
+	"${test}XXX" \
+	"${addr}XXX"
+
+# Test abstract seqpacket server and client
+do_test "abstract" \
+	"server" \
+	"create,setopt" \
+	"bind,listen,getopt,shutdown" \
+	seqpacket \
+	"$addr" \
+	"accept,read,write" \
+	"unconfined" \
+	"" \
+	stream \
+	"${addr}XXX" \
+	"XXX" \
+	""
+do_test "abstract" \
+	"client" \
+	"" \
+	"create,getopt,setopt,getattr" \
+	seqpacket \
+	"" \
+	"connect,write,read" \
+	"$test" \
+	"$addr" \
+	dgram \
+	"" \
+	"${test}XXX" \
+	"${addr}XXX"
-- 
2.1.0




More information about the AppArmor mailing list