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 <[email protected]>
---
 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


-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to