[PATCH v2] selinux-testsuite: fix unix/inet socket tests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There was a bug in the unix and inet socket tests:
the server program would exit as soon as it finished
responding to the legitimate client, so the unauthorized
client tests were "succeeding" due to the server socket
not even existing rather than a permission denial.  Fix
the server to stay around until it is explicitly killed by
the test scripts.  This fix then revealed a problem with the
last inet_socket test: although the permission denial correctly
prevents the server from receiving the datagram message, the
client gets no notification of this failure and hangs on its
subsequent attempt to read a reply from the server.  Add a call
to poll() with a timeout so that the client can handle this
situation.

Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx>
---
v2 fixes the last test by adding a call to poll() to the client
rather than removing the test.  This enables the test to pass but
does make it dependent on timing; the authorized client could
fail the test if the server does not reply within the specified
timeout on a loaded system.

 tests/inet_socket/client.c |  19 +++++++
 tests/inet_socket/server.c | 134 +++++++++++++++++++++++----------------------
 tests/unix_socket/server.c | 132 ++++++++++++++++++++++----------------------
 3 files changed, 156 insertions(+), 129 deletions(-)

diff --git a/tests/inet_socket/client.c b/tests/inet_socket/client.c
index ffc154c..a0273af 100644
--- a/tests/inet_socket/client.c
+++ b/tests/inet_socket/client.c
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <poll.h>
 #include <selinux/selinux.h>
 
 void usage(char *progname)
@@ -76,6 +77,24 @@ main(int argc, char **argv)
 		close(sock);
 		exit(1);
 	}
+
+	if (type == SOCK_DGRAM) {
+		struct pollfd fds;
+		struct timespec timeout;
+
+		fds.fd = sock;
+		fds.events = POLLIN;
+		result = poll(&fds, 1, 1000);
+		if (result < 0) {
+			perror("poll");
+			close(sock);
+			exit(1);
+		} else if (result == 0) {
+			fprintf(stderr, "%s: no reply from server\n", argv[0]);
+			exit(1);
+		}
+	}
+
 	result = read(sock, label, sizeof(label));
 	if (result < 0) {
 		perror("read");
diff --git a/tests/inet_socket/server.c b/tests/inet_socket/server.c
index f7f4fdd..630d988 100644
--- a/tests/inet_socket/server.c
+++ b/tests/inet_socket/server.c
@@ -80,46 +80,48 @@ main(int argc, char **argv)
 	}
 
 	if (type == SOCK_STREAM) {
-		int newsock;
-		char peerlabel[256];
-		socklen_t labellen = sizeof(peerlabel);
-
 		if (listen(sock, SOMAXCONN)) {
 			perror("listen");
 			close(sock);
 			exit(1);
 		}
 
-		sinlen = sizeof(sin);
-		newsock = accept(sock, (struct sockaddr *)&sin,
-				 &sinlen);
-		if (newsock < 0) {
-			perror("accept");
-			close(sock);
-			exit(1);
-		}
+		do {
+			int newsock;
+			char peerlabel[256];
+			socklen_t labellen = sizeof(peerlabel);
+
+			sinlen = sizeof(sin);
+			newsock = accept(sock, (struct sockaddr *)&sin,
+					 &sinlen);
+			if (newsock < 0) {
+				perror("accept");
+				close(sock);
+				exit(1);
+			}
 
-		peerlabel[0] = 0;
-		result = getsockopt(newsock, SOL_SOCKET, SO_PEERSEC, peerlabel,
-				    &labellen);
-		if (result < 0) {
-			perror("getsockopt: SO_PEERSEC");
-			exit(1);
-		}
-		printf("%s:  Got peer label=%s\n", argv[0], peerlabel);
+			peerlabel[0] = 0;
+			result = getsockopt(newsock, SOL_SOCKET, SO_PEERSEC, peerlabel,
+					    &labellen);
+			if (result < 0) {
+				perror("getsockopt: SO_PEERSEC");
+				exit(1);
+			}
+			printf("%s:  Got peer label=%s\n", argv[0], peerlabel);
 
-		result = read(newsock, &byte, 1);
-		if (result < 0) {
-			perror("read");
-			exit(1);
-		}
+			result = read(newsock, &byte, 1);
+			if (result < 0) {
+				perror("read");
+				exit(1);
+			}
 
-		result = write(newsock, peerlabel, strlen(peerlabel));
-		if (result < 0) {
-			perror("write");
-			exit(1);
-		}
-		close(newsock);
+			result = write(newsock, peerlabel, strlen(peerlabel));
+			if (result < 0) {
+				perror("write");
+				exit(1);
+			}
+			close(newsock);
+		} while (1);
 	} else {
 		struct iovec iov;
 		struct msghdr msg;
@@ -130,43 +132,45 @@ main(int argc, char **argv)
 			char buf[CMSG_SPACE(sizeof(msglabel))];
 		} control;
 
-		memset(&iov, 0, sizeof(iov));
-		iov.iov_base = &byte;
-		iov.iov_len = 1;
-		memset(&msg, 0, sizeof(msg));
-		msglabel[0] = 0;
-		msg.msg_name = &sin;
-		msg.msg_namelen = sizeof(sin);
-		msg.msg_iov = &iov;
-		msg.msg_iovlen = 1;
-		msg.msg_control = &control;
-		msg.msg_controllen = sizeof(control);
-		result = recvmsg(sock, &msg, 0);
-		if (result < 0) {
-			perror("recvmsg");
-			exit(1);
-		}
-		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
-		     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-			if (cmsg->cmsg_level == SOL_IP &&
-			    cmsg->cmsg_type == SCM_SECURITY) {
-				size_t len = cmsg->cmsg_len - CMSG_LEN(0);
-
-				if (len > 0 && len < sizeof(msglabel)) {
-					memcpy(msglabel, CMSG_DATA(cmsg), len);
-					msglabel[len] = 0;
-					printf("%s: Got SCM_SECURITY=%s\n",
-					       argv[0], msglabel);
+		do {
+			memset(&iov, 0, sizeof(iov));
+			iov.iov_base = &byte;
+			iov.iov_len = 1;
+			memset(&msg, 0, sizeof(msg));
+			msglabel[0] = 0;
+			msg.msg_name = &sin;
+			msg.msg_namelen = sizeof(sin);
+			msg.msg_iov = &iov;
+			msg.msg_iovlen = 1;
+			msg.msg_control = &control;
+			msg.msg_controllen = sizeof(control);
+			result = recvmsg(sock, &msg, 0);
+			if (result < 0) {
+				perror("recvmsg");
+				exit(1);
+			}
+			for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+			     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+				if (cmsg->cmsg_level == SOL_IP &&
+				    cmsg->cmsg_type == SCM_SECURITY) {
+					size_t len = cmsg->cmsg_len - CMSG_LEN(0);
+
+					if (len > 0 && len < sizeof(msglabel)) {
+						memcpy(msglabel, CMSG_DATA(cmsg), len);
+						msglabel[len] = 0;
+						printf("%s: Got SCM_SECURITY=%s\n",
+						       argv[0], msglabel);
+					}
 				}
 			}
-		}
 
-		result = sendto(sock, msglabel, strlen(msglabel), 0,
-				msg.msg_name, msg.msg_namelen);
-		if (result < 0) {
-			perror("sendto");
-			exit(1);
-		}
+			result = sendto(sock, msglabel, strlen(msglabel), 0,
+					msg.msg_name, msg.msg_namelen);
+			if (result < 0) {
+				perror("sendto");
+				exit(1);
+			}
+		} while (1);
 	}
 
 	close(sock);
diff --git a/tests/unix_socket/server.c b/tests/unix_socket/server.c
index 89bfdb3..e8958dd 100644
--- a/tests/unix_socket/server.c
+++ b/tests/unix_socket/server.c
@@ -70,45 +70,47 @@ main(int argc, char **argv)
 	}
 
 	if (type == SOCK_STREAM) {
-		int newsock;
-		char peerlabel[256];
-		socklen_t labellen = sizeof(peerlabel);
-
 		if (listen(sock, SOMAXCONN)) {
 			perror("listen");
 			close(sock);
 			exit(1);
 		}
 
-		newsock = accept(sock, (struct sockaddr *)&remotesun,
-				 &remotesunlen);
-		if (newsock < 0) {
-			perror("accept");
-			close(sock);
-			exit(1);
-		}
+		do {
+			int newsock;
+			char peerlabel[256];
+			socklen_t labellen = sizeof(peerlabel);
+
+			newsock = accept(sock, (struct sockaddr *)&remotesun,
+					 &remotesunlen);
+			if (newsock < 0) {
+				perror("accept");
+				close(sock);
+				exit(1);
+			}
 
-		peerlabel[0] = 0;
-		result = getsockopt(newsock, SOL_SOCKET, SO_PEERSEC, peerlabel,
-				    &labellen);
-		if (result < 0) {
-			perror("getsockopt: SO_PEERSEC");
-			exit(1);
-		}
-		printf("%s:  Got peer label=%s\n", argv[0], peerlabel);
+			peerlabel[0] = 0;
+			result = getsockopt(newsock, SOL_SOCKET, SO_PEERSEC, peerlabel,
+					    &labellen);
+			if (result < 0) {
+				perror("getsockopt: SO_PEERSEC");
+				exit(1);
+			}
+			printf("%s:  Got peer label=%s\n", argv[0], peerlabel);
 
-		result = read(newsock, &byte, 1);
-		if (result < 0) {
-			perror("read");
-			exit(1);
-		}
+			result = read(newsock, &byte, 1);
+			if (result < 0) {
+				perror("read");
+				exit(1);
+			}
 
-		result = write(newsock, peerlabel, strlen(peerlabel));
-		if (result < 0) {
-			perror("write");
-			exit(1);
-		}
-		close(newsock);
+			result = write(newsock, peerlabel, strlen(peerlabel));
+			if (result < 0) {
+				perror("write");
+				exit(1);
+			}
+			close(newsock);
+		} while (1);
 	} else {
 		struct iovec iov;
 		struct msghdr msg;
@@ -119,43 +121,45 @@ main(int argc, char **argv)
 			char buf[CMSG_SPACE(sizeof(msglabel))];
 		} control;
 
-		memset(&iov, 0, sizeof(iov));
-		iov.iov_base = &byte;
-		iov.iov_len = 1;
-		memset(&msg, 0, sizeof(msg));
-		msglabel[0] = 0;
-		msg.msg_name = &remotesun;
-		msg.msg_namelen = remotesunlen;
-		msg.msg_iov = &iov;
-		msg.msg_iovlen = 1;
-		msg.msg_control = &control;
-		msg.msg_controllen = sizeof(control);
-		result = recvmsg(sock, &msg, 0);
-		if (result < 0) {
-			perror("recvmsg");
-			exit(1);
-		}
-		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
-		     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-			if (cmsg->cmsg_level == SOL_SOCKET &&
-			    cmsg->cmsg_type == SCM_SECURITY) {
-				size_t len = cmsg->cmsg_len - CMSG_LEN(0);
-
-				if (len > 0 && len < sizeof(msglabel)) {
-					memcpy(msglabel, CMSG_DATA(cmsg), len);
-					msglabel[len] = 0;
-					printf("%s: Got SCM_SECURITY=%s\n",
-					       argv[0], msglabel);
+		do {
+			memset(&iov, 0, sizeof(iov));
+			iov.iov_base = &byte;
+			iov.iov_len = 1;
+			memset(&msg, 0, sizeof(msg));
+			msglabel[0] = 0;
+			msg.msg_name = &remotesun;
+			msg.msg_namelen = remotesunlen;
+			msg.msg_iov = &iov;
+			msg.msg_iovlen = 1;
+			msg.msg_control = &control;
+			msg.msg_controllen = sizeof(control);
+			result = recvmsg(sock, &msg, 0);
+			if (result < 0) {
+				perror("recvmsg");
+				exit(1);
+			}
+			for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+			     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+				if (cmsg->cmsg_level == SOL_SOCKET &&
+				    cmsg->cmsg_type == SCM_SECURITY) {
+					size_t len = cmsg->cmsg_len - CMSG_LEN(0);
+
+					if (len > 0 && len < sizeof(msglabel)) {
+						memcpy(msglabel, CMSG_DATA(cmsg), len);
+						msglabel[len] = 0;
+						printf("%s: Got SCM_SECURITY=%s\n",
+						       argv[0], msglabel);
+					}
 				}
 			}
-		}
 
-		result = sendto(sock, msglabel, strlen(msglabel), 0,
-				msg.msg_name, msg.msg_namelen);
-		if (result < 0) {
-			perror("sendto");
-			exit(1);
-		}
+			result = sendto(sock, msglabel, strlen(msglabel), 0,
+					msg.msg_name, msg.msg_namelen);
+			if (result < 0) {
+				perror("sendto");
+				exit(1);
+			}
+		} while (1);
 	}
 
 	close(sock);
-- 
2.1.0

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux