[apparmor] [PATCH 4/6] tests: Migrate unix_socket tests from poll to sock IO timeouts

Tyler Hicks tyhicks at canonical.com
Thu Sep 4 11:55:44 UTC 2014


Update unix_socket and unix_socket_client to use setsockopt() in order
to set send and receive timeouts for socket IO operations. This takes
the place of poll(). Poll() was not being used for all potentially
blocking socket operations which could have resulted in test cases
blocking infinitely.

This also has the nice side effect of using getsockopt() and
setsockopt(). These are AppArmor mediation points in kernel ABI v7 so it
is worthwhile to test the calls while under confinement.

This patch updates the existing v7 policy generation to allow the getopt
and setopt accesses.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 tests/regression/apparmor/unix_socket.c        | 43 +++++++++++++++++++-------
 tests/regression/apparmor/unix_socket.sh       | 13 +++++---
 tests/regression/apparmor/unix_socket_client.c | 34 ++++++++++++++++++++
 3 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/tests/regression/apparmor/unix_socket.c b/tests/regression/apparmor/unix_socket.c
index b6dc0dd..50ae8e8 100644
--- a/tests/regression/apparmor/unix_socket.c
+++ b/tests/regression/apparmor/unix_socket.c
@@ -14,7 +14,6 @@
  * along with this program; if not, contact Canonical Ltd.
  */
 
-#include <poll.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -81,10 +80,39 @@ static int connectionless_messaging(int sock, char *msg_buf, size_t msg_buf_len)
 	return 0;
 }
 
+static int get_set_sock_io_timeo(int sock)
+{
+	struct timeval tv;
+	socklen_t tv_len = sizeof(tv);
+	int rc;
+
+	rc = getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, &tv_len);
+	if (rc == -1) {
+		perror("FAIL - getsockopt");
+		return 1;
+	}
+
+	tv.tv_sec = 1;
+	tv.tv_usec = 0;
+
+	rc = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, tv_len);
+	if (rc == -1) {
+		perror("FAIL - setsockopt (SO_RCVTIMEO)");
+		return 1;
+	}
+
+	rc = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, tv_len);
+	if (rc == -1) {
+		perror("FAIL - setsockopt (SO_SNDTIMEO)");
+		return 1;
+	}
+
+	return 0;
+}
+
 int main (int argc, char *argv[])
 {
 	struct sockaddr_un addr;
-	struct pollfd pfd;
 	char msg_buf[MSG_BUF_MAX];
 	size_t msg_buf_len;
 	const char *sun_path;
@@ -162,16 +190,9 @@ int main (int argc, char *argv[])
 		exit(0);
 	}
 
-	pfd.fd = sock;
-	pfd.events = POLLIN;
-	rc = poll(&pfd, 1, 500);
-	if (rc < 0) {
-		perror("FAIL - poll");
-		exit(1);
-	} else if (!rc) {
-		fprintf(stderr, "FAIL - poll timed out\n");
+	rc = get_set_sock_io_timeo(sock);
+	if (rc)
 		exit(1);
-	}
 
 	rc = (type & SOCK_STREAM || type & SOCK_SEQPACKET) ?
 		connection_based_messaging(sock, msg_buf, msg_buf_len) :
diff --git a/tests/regression/apparmor/unix_socket.sh b/tests/regression/apparmor/unix_socket.sh
index 8fd70dd..0b36b4f 100755
--- a/tests/regression/apparmor/unix_socket.sh
+++ b/tests/regression/apparmor/unix_socket.sh
@@ -63,12 +63,17 @@ testsocktype()
 
 	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")
+		okservers=("$sockpath:rw unix:(create,getopt,setopt)")
 		badservers=("" \
-			    "$sockpath:r unix:create" \
-			    "$sockpath:w unix:create" \
-			    "unix:create" \
+			    "$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[@]}")
diff --git a/tests/regression/apparmor/unix_socket_client.c b/tests/regression/apparmor/unix_socket_client.c
index ac53ecd..c0892cf 100644
--- a/tests/regression/apparmor/unix_socket_client.c
+++ b/tests/regression/apparmor/unix_socket_client.c
@@ -78,6 +78,36 @@ static int connectionless_messaging(int sock)
 	return 0;
 }
 
+static int get_set_sock_io_timeo(int sock)
+{
+	struct timeval tv;
+	socklen_t tv_len = sizeof(tv);
+	int rc;
+
+	rc = getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, &tv_len);
+	if (rc == -1) {
+		perror("FAIL - getsockopt");
+		return 1;
+	}
+
+	tv.tv_sec = 1;
+	tv.tv_usec = 0;
+
+	rc = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, tv_len);
+	if (rc == -1) {
+		perror("FAIL - setsockopt (SO_RCVTIMEO)");
+		return 1;
+	}
+
+	rc = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, tv_len);
+	if (rc == -1) {
+		perror("FAIL - setsockopt (SO_SNDTIMEO)");
+		return 1;
+	}
+
+	return 0;
+}
+
 int main(int argc, char *argv[])
 {
 	struct sockaddr_un peer_addr;
@@ -122,6 +152,10 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
+	rc = get_set_sock_io_timeo(sock);
+	if (rc)
+		exit(1);
+
 	rc = connect(sock, (struct sockaddr *)&peer_addr,
 		     sun_path_len + sizeof(peer_addr.sun_family));
 	if (rc < 0) {
-- 
2.1.0




More information about the AppArmor mailing list