[apparmor] [PATCH 5/6] tests: Add abstract socket tests to unix_socket.sh
Tyler Hicks
tyhicks at canonical.com
Thu Sep 4 11:55:45 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.
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
tests/regression/apparmor/unix_socket.sh | 176 ++++++++++++++++++++-----------
1 file changed, 117 insertions(+), 59 deletions(-)
diff --git a/tests/regression/apparmor/unix_socket.sh b/tests/regression/apparmor/unix_socket.sh
index 0b36b4f..7c23464 100755
--- a/tests/regression/apparmor/unix_socket.sh
+++ b/tests/regression/apparmor/unix_socket.sh
@@ -31,7 +31,9 @@ requires_features policy/versions/v6
client=$bin/unix_socket_client
sockpath_pathname=${tmpdir}/unix_socket.sock
+bad_sockpath_pathname="${sockpath_pathname}XXX"
sockpath_abstract="@apparmor_unix_socket"
+bad_sockpath_abstract="${sockpath_abstract}XXX"
message=4a0c83d87aaa7afa2baab5df3ee4df630f0046d5bfb7a3080c550b721f401b3b\
8a738e1435a3b77aa6482a70fb51c44f20007221b85541b0184de66344d46a4c
@@ -51,32 +53,117 @@ testsocktype()
{
local testdesc=$1 # description (eg, "AF_UNIX abstract socket (dgram)")
local sockpath=$2 # fs path or "@NAME" for an abstract sock
- local socktype=$3 # stream, dgram, or seqpacket
+ local bad_sockpath=$3
+ local socktype=$4 # stream, dgram, or seqpacket
+ local bad_socktype=$5
local args="$sockpath $socktype $message $client"
local i=0
+ local okservers
+ local badservers
+ local okclients
+ local badclients
- # assume, by default, that the sock addr is of the pathname type
- local okservers=("$sockpath:w")
- local badservers=("" "$sockpath:r")
- local okclients=("$sockpath:rw")
- local badclients=("" "$sockpath:r" "$sockpath:w")
-
- if [ "$(have_features policy/versions/v7)" == "true" ] ; then
- # v7 requires 'unix create' to call socket()
- # v7 requires 'unix getopt' to call getsockopt()
- # v7 requires 'unix setopt' to call setsockopt()
- # v7 requires 'rw' for the server
- okservers=("$sockpath:rw unix:(create,getopt,setopt)")
- badservers=("" \
- "$sockpath:r unix:(create,getopt,setopt)" \
- "$sockpath:w unix:(create,getopt,setopt)" \
- "unix:(create,getopt,setopt)" \
- "$sockpath:rw unix:(getopt,setopt)" \
- "$sockpath:rw unix:(create,setopt)" \
- "$sockpath:rw unix:(create,getopt)" \
- )
- okclients=("${okservers[@]}")
- badclients=("${badservers[@]}")
+ if isabstract $sockpath; then
+ local ls_access # local server accesses
+ local ps_access # peer server accesses
+ local s_access # combined server accesses
+
+ local lc_access # local client accesses
+ local pc_access # peer client accesses
+ local c_access # combined client accesses
+
+ local access # used for iterating accesses
+
+ if [ "$socktype" == "dgram" ]; then
+ # Connectionless
+ # Server doesn't listen() or accept()
+ ls_access="create,bind,getopt,setopt"
+ ps_access="read,write"
+
+ # Client calls bind()
+ lc_access="${client_create}bind,getopt,setopt"
+ pc_access="connect,write,read"
+ else # stream or seqpacket
+ # Connection based
+ # Server calls listen() and accept()
+ ls_access="create,bind,listen,getopt,setopt"
+ ps_access="accept,read,write"
+
+ # Client doesn't call bind()
+ lc_access="${client_create}getopt,setopt"
+ pc_access="connect,write,read"
+ fi
+
+ s_access="${ls_access},${ps_access}"
+ c_access="${lc_access},${pc_access}"
+
+ okservers=("unix:ALL" \
+ "unix:($s_access)" \
+ "unix:addr=$sockpath" \
+ "unix:type=$socktype" \
+ "unix:peer=(label=unconfined)" \
+ "unix:($s_access):addr=$sockpath" \
+ "unix:($ls_access):addr=$sockpath unix:($ps_access):addr=$sockpath:peer=(label=unconfined)" \
+ "unix:($ls_access):type=$socktype:addr=$sockpath unix:($ps_access):type=$socktype:addr=$sockpath:peer=(label=unconfined)" \
+ "unix:type=$socktype:addr=$sockpath:peer=(label=unconfined)" \
+ )
+ # Start with no accessess, then remove each access one-by-one
+ # from the list of server accesses, and then test bad
+ # conditional values
+ badservers=("")
+ for access in ${s_access/,/ }; do
+ badservers+=("unix:(${s_access//$access/})")
+ done
+ badservers+=("unix:addr=$bad_sockpath" \
+ "unix:type=$bad_socktype" \
+ "unix:peer=(label=XXX)" \
+ )
+
+ okclients=("unix:ALL" \
+ "unix:($c_access)" \
+ "unix:addr=$sockpath" \
+ "unix:type=$socktype" \
+ "unix:peer=(label=$test)" \
+ "unix:($c_access):addr=$sockpath" \
+ "unix:($lc_access):addr=$sockpath unix:($pc_access):addr=$sockpath:peer=(label=$test)" \
+ "unix:($lc_access):type=$socktype:addr=$sockpath unix:($pc_access):type=$socktype:addr=$sockpath:peer=(label=$test)" \
+ "unix:type=$socktype:addr=$sockpath:peer=(label=$test)" \
+ )
+ # Start with no accessess, then remove each access one-by-one
+ # from the list of client accesses, and then test bad
+ # conditional values
+ badclients=("")
+ for access in ${c_access/,/ }; do
+ badclients+=("unix:(${c_access//$access/})")
+ done
+ badclients+=("unix:addr=$bad_sockpath" \
+ "unix:type=$bad_socktype" \
+ "unix:peer=(label=XXX)" \
+ )
+ else # pathname-based UNIX domain socket
+ if [ "$(have_features policy/versions/v7)" == "true" ] ; then
+ # v7 requires 'unix create' to call socket()
+ # v7 requires 'unix getopt' to call getsockopt()
+ # v7 requires 'unix setopt' to call setsockopt()
+ # v7 requires 'rw' for the server
+ okservers=("$sockpath:rw unix:(create,getopt,setopt)")
+ badservers=("" \
+ "$sockpath:r unix:(create,getopt,setopt)" \
+ "$sockpath:w unix:(create,getopt,setopt)" \
+ "unix:(create,getopt,setopt)" \
+ "$sockpath:rw unix:(getopt,setopt)" \
+ "$sockpath:rw unix:(create,setopt)" \
+ "$sockpath:rw unix:(create,getopt)" \
+ )
+ okclients=("${okservers[@]}")
+ badclients=("${badservers[@]}")
+ else
+ # v6 only requires 'w' for the server
+ okservers=("$sockpath:w")
+ badservers=("" "$sockpath:r")
+ okclients=("$sockpath:rw")
+ badclients=("" "$sockpath:r" "$sockpath:w")
+ fi
fi
removesocket $sockpath
@@ -86,15 +173,6 @@ testsocktype()
runchecktest "$testdesc; unconfined" pass $args
removesocket $sockpath
- # TODO: Make additional changes to test abstract sockets w/ confinement
- #
- # * Create variables to hold genprofile arguments for socket accesses
- # and initialize them according to socket address type
- # * Remove the following conditional
- if isabstract $sockpath; then
- return
- fi
-
for ((i=0; i<${#okservers[@]}; i++)); do
# PASS - server w/ access to the file
@@ -132,32 +210,12 @@ testsocktype()
testsockpath()
{
- local sockpath="$1" # $sockpath_pathname or $sockpath_abstract
- local testdesc="AF_UNIX "
- local socktype=
-
- if [ "$sockpath" == "$sockpath_pathname" ]; then
- testdesc+="pathname socket"
- elif [ "$sockpath" == "$sockpath_abstract" ]; then
- testdesc+="abstract socket"
- else
- fatalerror "Unknown sockpath addr type: $sockpath"
- fi
-
- for socktype in stream dgram seqpacket; do
- testsocktype "$testdesc ($socktype)" "$sockpath" "$socktype"
- done
+ testsocktype "AF_UNIX $1 (stream)" "$2" "$3" stream dgram
+ testsocktype "AF_UNIX $1 (dgram)" "$2" "$3" dgram seqpacket
+ testsocktype "AF_UNIX $1 (seqpacket)" "$2" "$3" seqpacket stream
}
-testsockpath "$sockpath_pathname"
-testsockpath "$sockpath_abstract"
-# TODO: testsockpath "$sockpath_unnamed"
-#
-# * Adjust unix_socket.c and unix_socket_client.c when the socket path is
-# "UNNAMED"
-# - Don't bind() the socket
-# - Don't set SO_CLOEXEC so that the fd can be passed over exec()
-# * Decide how to generate appropriate access rules (if any are needed)
-# * Define sockpath_unnamed as "UNNAMED"
-# * Update testsockpath() to handle sockpath_unnamed
-# * Create isunnamed() and update removesocket() to call it
+testsockpath "pathname socket" "$sockpath_pathname" "$bad_sockpath_pathname"
+if [ "$(have_features network/af_unix)" == "true" ] ; then
+ testsockpath "abstract socket" "$sockpath_abstract" "$bad_sockpath_abstract"
+fi
--
2.1.0
More information about the AppArmor
mailing list