xref: /minix/minix/tests/test56.c (revision 27852ebe)
1 /*
2  * Test Program for Unix Domain Sockets
3  *
4  * Overview: This program tests Unix Domain Sockets. It attempts
5  * to exercise the functions associated with Unix Domain Sockets.
6  * It also attempts to make sure all of the functions which handle
7  * file/socket descriptors work correctly when given a socket
8  * descriptor for a Unix domain socket. It also implicitly checks
9  * for the existance of constants like AF_UNIX and structures like
10  * sockaddr_un (it won't compile if they aren't defined). Besides
11  * checking that the sockets work properly, this test program also
12  * checks that the errors returned conform to the POSIX 2008
13  * standards. Some tests are omitted as they could adversely affect
14  * the operation of the host system. For example, implementing a test
15  * for socket() failing with errno = ENFILE would require using up all
16  * of the file descriptors supported by the OS (defined in
17  * /proc/sys/fs/file-max on Linux); this could cause problems for
18  * daemons and other processes running on the system. Some tests are
19  * omitted because they would require changes to libc or the kernel.
20  * For example, getting EINTR would require  delaying the system call
21  * execution time long enough to raise a signal to interupt it. Some
22  * tests were omitted because the particular errors cannot occur when
23  * using Unix domain sockets. For example, write() will never fail with
24  * ENETDOWN because Unix domain sockets don't use network interfaces.
25  *
26  * Structure: Some functions can be tested or partially tested without
27  * making a connection, socket() for example. These have test
28  * functions like test_NAME(). The functionality that needs two way
29  * communication is contained within test_xfer().
30  *
31  * Functions Tested: accept(), bind(), close(), connect(), dup(),
32  * dup2(), fstat(), getpeername(), getsockname(), getsockopt(),
33  * listen(), read(), readv(), recv(), recvfrom(), recvmsg(), select(),
34  * send(), sendmsg(), sendto(), setsockopt(), shutdown(), socket(),
35  * socketpair(), write(), writev()
36  */
37 
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <signal.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <stddef.h>
46 #include <sys/socket.h>
47 #include <sys/ucred.h>
48 #include <sys/stat.h>
49 #include <sys/time.h>
50 #include <sys/types.h>
51 #include <sys/uio.h>
52 #include <sys/un.h>
53 #include <sys/wait.h>
54 #include <time.h>
55 #include <unistd.h>
56 
57 /* Maximum number of errors that we'll allow to occur before this test
58  * program gives us and quits.
59  */
60 int max_error = 4;
61 #include "common.h"
62 #include "common-socket.h"
63 
64 
65 /* Use the common testing code instead of reinventing the wheel. */
66 
67 /* path of the unix domain socket */
68 #define TEST_SUN_PATH "test.sock"
69 #define TEST_SUN_PATHB "testb.sock"
70 
71 /* filenames for symlinks -- we link these to each other to test ELOOP .*/
72 #define TEST_SYM_A "test.a"
73 #define TEST_SYM_B "test.b"
74 
75 /* text file and test phrase for testing file descriptor passing */
76 #define TEST_TXT_FILE "test.txt"
77 #define MSG "This raccoon loves to eat bugs.\n"
78 
79 /* socket types supported */
80 static int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM};
81 
test_header(void)82 static void test_header(void)
83 {
84 	struct sockaddr_un sun;
85 	debug("entering test_header()");
86 
87 	sun.sun_family = AF_UNIX;
88 	sun.sun_path[0] = 'x';
89 	sun.sun_path[1] = 'x';
90 	sun.sun_path[2] = 'x';
91 	sun.sun_path[3] = '\0';
92 
93 	if (SUN_LEN(&sun) != 5) {
94 		test_fail("SUN_LEN(&sun) should be 5");
95 	}
96 
97 	if (PF_UNIX != PF_LOCAL || PF_UNIX != AF_UNIX) {
98 		test_fail("PF_UNIX, PF_LOCAL and AF_UNIX");
99 	}
100 }
101 
test_socketpair(void)102 static void test_socketpair(void)
103 {
104 	char buf[128];
105 	struct sockaddr_un addr;
106 	int socket_vector[2];
107 	int rc;
108 	int i;
109 
110 	debug("entering test_socketpair()");
111 
112 	UNLINK(TEST_SUN_PATH);
113 	memset(&addr, '\0', sizeof(struct sockaddr_un));
114 	addr.sun_family = AF_UNIX;
115 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
116 
117 	debug("Testing socketpair() success");
118 
119 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
120 	if (rc == -1) {
121 		test_fail("socketpair() should have worked");
122 	}
123 
124 	debug("Testing a simple read/write using sockets from socketpair()");
125 	memset(buf, '\0', sizeof(buf));
126 
127 	strncpy(buf, "Howdy Partner", sizeof(buf) - 1);
128 
129 	rc = write(socket_vector[0], buf, sizeof(buf));
130 	if (rc == -1) {
131 		test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
132 	}
133 
134 	memset(buf, '\0', sizeof(buf));
135 
136 	rc = read(socket_vector[1], buf, sizeof(buf));
137 	if (rc == -1) {
138 		test_fail("read() failed unexpectedly");
139 	}
140 
141 	if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) {
142 		test_fail("We did not read what we wrote");
143 	}
144 
145 	CLOSE(socket_vector[0]);
146 	CLOSE(socket_vector[1]);
147 
148 	debug("Test socketpair() with all FDs open by this process");
149 
150 	for (i = 3; i < getdtablesize(); i++) {
151 		rc = open("/dev/null", O_RDONLY);
152 		if (rc == -1) {
153 			test_fail("we couldn't open /dev/null for read");
154 		}
155 	}
156 
157 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector);
158 	if (!(rc == -1 && errno == EMFILE)) {
159 		test_fail("socketpair() should have failed with EMFILE");
160 	}
161 
162 	for (i = 3; i < getdtablesize(); i++) {
163 		CLOSE(i);
164 	}
165 
166 	rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector);
167 	if (!(rc == -1 && errno == EPROTONOSUPPORT)) {
168 		test_fail("socketpair() should have failed");
169 	}
170 
171 	debug("leaving test_socketpair()");
172 }
173 
test_ucred(void)174 static void test_ucred(void)
175 {
176 	struct unpcbid credentials;
177 	socklen_t ucred_length;
178 	uid_t euid = geteuid();
179 	gid_t egid = getegid();
180 	int sv[2];
181 	int rc;
182 
183 	debug("Test peer credentials");
184 
185 	ucred_length = sizeof(credentials);
186 
187 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
188 	if (rc == -1) {
189 		test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
190 	}
191 
192 	memset(&credentials, '\0', ucred_length);
193 	rc = getsockopt(sv[0], 0, LOCAL_PEEREID, &credentials,
194 							&ucred_length);
195 	if (rc == -1) {
196 		test_fail("getsockopt(LOCAL_PEEREID) failed");
197 	} else if (credentials.unp_pid != getpid() ||
198 			credentials.unp_euid != geteuid() ||
199 			credentials.unp_egid != getegid()) {
200 		printf("%d=%d %d=%d %d=%d",credentials.unp_pid, getpid(),
201 		    credentials.unp_euid, geteuid(),
202 		    credentials.unp_egid, getegid());
203 		test_fail("Credential passing gave us the wrong cred");
204 	}
205 
206 	rc = getpeereid(sv[0], &euid, &egid);
207 	if (rc == -1) {
208 		test_fail("getpeereid(sv[0], &euid, &egid) failed");
209 	} else if (credentials.unp_euid != euid ||
210 	    credentials.unp_egid != egid) {
211 		test_fail("getpeereid() didn't give the correct euid/egid");
212 	}
213 
214 	CLOSE(sv[0]);
215 	CLOSE(sv[1]);
216 }
217 
callback_check_sockaddr(const struct sockaddr * sockaddr,socklen_t sockaddrlen,const char * callname,int addridx)218 static void callback_check_sockaddr(const struct sockaddr *sockaddr,
219 	socklen_t sockaddrlen, const char *callname, int addridx) {
220 	char buf[256];
221 	const char *path;
222 	const struct sockaddr_un *sockaddr_un =
223 		(const struct sockaddr_un *) sockaddr;
224 
225 	switch (addridx) {
226 	case 1: path = TEST_SUN_PATH; break;
227 	case 2: path = TEST_SUN_PATHB; break;
228 	default:
229 		fprintf(stderr, "error: invalid addridx %d in "
230 			"callback_check_sockaddr\n", addridx);
231 		abort();
232 	}
233 
234 	if (!(sockaddr_un->sun_family == AF_UNIX &&
235 			strncmp(sockaddr_un->sun_path,
236 			path,
237 			sizeof(sockaddr_un->sun_path) - 1) == 0)) {
238 
239 		snprintf(buf, sizeof(buf), "%s() didn't return the right addr",
240 			callname);
241 		test_fail(buf);
242 		fprintf(stderr, "exp: '%s' | got: '%s'\n", path,
243 			sockaddr_un->sun_path);
244 	}
245 }
246 
callback_cleanup(void)247 static void callback_cleanup(void) {
248 	UNLINK(TEST_SUN_PATH);
249 	UNLINK(TEST_SUN_PATHB);
250 	UNLINK(TEST_SYM_A);
251 	UNLINK(TEST_SYM_B);
252 }
253 
test_bind_unix(void)254 static void test_bind_unix(void)
255 {
256 	struct sockaddr_un addr;
257 	int sd;
258 	int rc;
259 
260 	debug("entering test_bind_unix()");
261 	UNLINK(TEST_SUN_PATH);
262 	memset(&addr, '\0', sizeof(struct sockaddr_un));
263 	addr.sun_family = AF_UNIX;
264 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
265 
266 	debug("Test bind() with an empty sun_path");
267 
268 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
269 	memset(addr.sun_path, '\0', sizeof(addr.sun_path));
270 	errno = 0;
271 
272 	rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
273 	if (!(rc == -1 && errno == ENOENT)) {
274 		test_fail("bind() should have failed with ENOENT");
275 	}
276 	CLOSE(sd);
277 
278 	debug("Test bind() using a symlink loop");
279 
280 	UNLINK(TEST_SUN_PATH);
281 	UNLINK(TEST_SYM_A);
282 	UNLINK(TEST_SYM_B);
283 
284 	SYMLINK(TEST_SYM_B, TEST_SYM_A);
285 
286 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
287 
288 	strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
289 	errno = 0;
290 	rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
291 	if (!((rc == -1) && (errno == EADDRINUSE))) {
292 		test_fail("bind() should have failed with EADDRINUSE");
293 	}
294 	CLOSE(sd);
295 
296 	SYMLINK(TEST_SYM_A, TEST_SYM_B);
297 
298 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
299 
300 	strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1);
301 	strlcat(addr.sun_path, "/x", sizeof(addr.sun_path));
302 	errno = 0;
303 	rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un));
304 	if (!((rc == -1) && (errno == ELOOP))) {
305 		test_fail("bind() should have failed with ELOOP");
306 	}
307 	CLOSE(sd);
308 
309 	UNLINK(TEST_SUN_PATH);
310 	UNLINK(TEST_SYM_A);
311 	UNLINK(TEST_SYM_B);
312 
313 	/* Test bind with garbage in sockaddr_un */
314 	memset(&addr, '?', sizeof(struct sockaddr_un));
315 	addr.sun_family = AF_UNIX;
316 	addr.sun_path[0] = 'f';
317 	addr.sun_path[1] = 'o';
318 	addr.sun_path[2] = 'o';
319 	addr.sun_path[3] = '\0';
320 	SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
321 	rc = bind(sd, (struct sockaddr *) &addr,
322 	    offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) +
323 	    1);
324 	if (rc == -1) {
325 		test_fail("bind() should have worked");
326 	}
327 	CLOSE(sd);
328 	UNLINK("foo");
329 
330 	debug("leaving test_bind_unix()");
331 }
332 
callback_xfer_prepclient(void)333 static void callback_xfer_prepclient(void) {
334 	debug("Creating symlink to TEST_SUN_PATH");
335 
336 	SYMLINK(TEST_SUN_PATH, TEST_SYM_A);
337 }
338 
callback_xfer_peercred(int sd)339 static void callback_xfer_peercred(int sd) {
340 	struct unpcbid credentials;
341 	int rc;
342 	socklen_t ucred_length;
343 
344 	ucred_length = sizeof(credentials);
345 
346 	debug("Test obtaining the peer credentials");
347 
348 	memset(&credentials, '\0', ucred_length);
349 	rc = getsockopt(sd, 0, LOCAL_PEEREID, &credentials, &ucred_length);
350 
351 	if (rc == -1) {
352 		test_fail("[client] getsockopt() failed");
353 	} else if (credentials.unp_euid != geteuid() ||
354 	    credentials.unp_egid != getegid()) {
355 		printf("%d=* %d=%d %d=%d", credentials.unp_pid,
356 		    credentials.unp_euid, geteuid(),
357 		    credentials.unp_egid, getegid());
358 		test_fail("[client] Credential passing gave us a bad UID/GID");
359 	}
360 }
361 
362 static void
callback_set_listen_opt(int sd)363 callback_set_listen_opt(int sd)
364 {
365 	int val;
366 
367 	/*
368 	 * Several of the tests assume that a new connection to a server will
369 	 * not be established (i.e., go from "connecting" to "connected" state)
370 	 * until the server actually accepts the connection with an accept(2)
371 	 * call.  With the new UDS implementation, this is no longer true: to
372 	 * match the behavior of other systems, UDS now preemptively connects
373 	 * the socket in anticipation of the accept(2) call.  We can change
374 	 * back to the old behavior by setting LOCAL_CONNWAIT however, and
375 	 * since the test effectively tests a larger set of socket transitions
376 	 * that way, that is what we do for these tests.
377 	 */
378 	val = 1;
379 	if (setsockopt(sd, 0, LOCAL_CONNWAIT, &val, sizeof(val)) != 0)
380 		test_fail("setsockopt(LOCAL_CONNWAIT)");
381 }
382 
test_vectorio(int type)383 static void test_vectorio(int type)
384 {
385 	int sv[2];
386 	int rc;
387 	struct iovec iov[3];
388 	char buf1[BUFSIZE];
389 	char buf2[BUFSIZE];
390 	char buf3[BUFSIZE];
391 	char buf4[BUFSIZE*3];
392 	const struct iovec *iovp = iov;
393 
394 	debug("begin vectorio tests");
395 
396 	memset(buf1, '\0', BUFSIZE);
397 	strncpy(buf1, "HELLO ", BUFSIZE - 1);
398 
399 	memset(buf2, '\0', BUFSIZE);
400 	strncpy(buf2, "WORLD", BUFSIZE - 1);
401 
402 	memset(buf3, '\0', BUFSIZE);
403 
404 	rc = socketpair(PF_UNIX, type, 0, sv);
405 	if (rc == -1) {
406 		test_fail("socketpair");
407 	}
408 
409 	iov[0].iov_base = buf1;
410 	iov[0].iov_len  = strlen(buf1);
411 	iov[1].iov_base = buf2;
412 	iov[1].iov_len  = strlen(buf2);
413 	iov[2].iov_base = buf3;
414 	iov[2].iov_len  = 1;
415 
416 	rc = writev(sv[0], iovp, 3);
417 	if (rc == -1) {
418 		test_fail("writev");
419 	}
420 
421 	memset(buf4, '\0', BUFSIZE*3);
422 
423 	rc = read(sv[1], buf4, BUFSIZE*3);
424 	if (rc == -1) {
425 		test_fail("read");
426 	}
427 
428 	if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
429 		test_fail("the string we read was not 'HELLO WORLD'");
430 	}
431 
432 	memset(buf1, '\0', BUFSIZE);
433 	strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
434 
435 	rc = write(sv[1], buf1, strlen(buf1) + 1);
436 	if (rc == -1) {
437 		test_fail("write");
438 	}
439 
440 	memset(buf2, '\0', BUFSIZE);
441 	memset(buf3, '\0', BUFSIZE);
442 	memset(buf4, '\0', BUFSIZE*3);
443 
444 	iov[0].iov_base = buf2;
445 	iov[0].iov_len  = 5;
446 	iov[1].iov_base = buf3;
447 	iov[1].iov_len  = 5;
448 	iov[2].iov_base = buf4;
449 	iov[2].iov_len  = 32;
450 
451 	rc = readv(sv[0], iovp, 3);
452 	if (rc == -1) {
453 		test_fail("readv");
454 	}
455 
456 	if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
457 					strncmp(buf4, "Time", 4)) {
458 		test_fail("readv");
459 	}
460 
461 	rc = close(sv[0]);
462 	if (rc == -1) {
463 		test_fail("close");
464 	}
465 
466 	rc = close(sv[1]);
467 	if (rc == -1) {
468 		test_fail("close");
469 	}
470 
471 	debug("done vector io tests");
472 }
473 
test_msg(int type)474 static void test_msg(int type)
475 {
476 	int sv[2];
477 	int rc;
478 	struct msghdr msg1;
479 	struct msghdr msg2;
480 	struct iovec iov[3];
481 	char buf1[BUFSIZE];
482 	char buf2[BUFSIZE];
483 	char buf3[BUFSIZE];
484 	char buf4[BUFSIZE*3];
485 
486 	debug("begin sendmsg/recvmsg tests");
487 
488 	memset(buf1, '\0', BUFSIZE);
489 	strncpy(buf1, "HELLO ", BUFSIZE - 1);
490 
491 	memset(buf2, '\0', BUFSIZE);
492 	strncpy(buf2, "WORLD", BUFSIZE - 1);
493 
494 	memset(buf3, '\0', BUFSIZE);
495 
496 	rc = socketpair(PF_UNIX, type, 0, sv);
497 	if (rc == -1) {
498 		test_fail("socketpair");
499 	}
500 
501 	iov[0].iov_base = buf1;
502 	iov[0].iov_len  = strlen(buf1);
503 	iov[1].iov_base = buf2;
504 	iov[1].iov_len  = strlen(buf2);
505 	iov[2].iov_base = buf3;
506 	iov[2].iov_len  = 1;
507 
508 	memset(&msg1, '\0', sizeof(struct msghdr));
509 	msg1.msg_name = NULL;
510 	msg1.msg_namelen = 0;
511 	msg1.msg_iov = iov;
512 	msg1.msg_iovlen = 3;
513 	msg1.msg_control = NULL;
514 	msg1.msg_controllen = 0;
515 	msg1.msg_flags = 0;
516 
517 	rc = sendmsg(sv[0], &msg1, 0);
518 	if (rc == -1) {
519 		test_fail("writev");
520 	}
521 
522 	memset(buf4, '\0', BUFSIZE*3);
523 
524 	rc = read(sv[1], buf4, BUFSIZE*3);
525 	if (rc == -1) {
526 		test_fail("read");
527 	}
528 
529 	if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) {
530 		test_fail("the string we read was not 'HELLO WORLD'");
531 	}
532 
533 	memset(buf1, '\0', BUFSIZE);
534 	strncpy(buf1, "Unit Test Time", BUFSIZE - 1);
535 
536 	rc = write(sv[1], buf1, strlen(buf1) + 1);
537 	if (rc == -1) {
538 		test_fail("write");
539 	}
540 
541 	memset(buf2, '\0', BUFSIZE);
542 	memset(buf3, '\0', BUFSIZE);
543 	memset(buf4, '\0', BUFSIZE*3);
544 
545 	iov[0].iov_base = buf2;
546 	iov[0].iov_len  = 5;
547 	iov[1].iov_base = buf3;
548 	iov[1].iov_len  = 5;
549 	iov[2].iov_base = buf4;
550 	iov[2].iov_len  = 32;
551 
552 	memset(&msg2, '\0', sizeof(struct msghdr));
553 	msg2.msg_name = NULL;
554 	msg2.msg_namelen = 0;
555 	msg2.msg_iov = iov;
556 	msg2.msg_iovlen = 3;
557 	msg2.msg_control = NULL;
558 	msg2.msg_controllen = 0;
559 	msg2.msg_flags = 0;
560 
561 	rc = recvmsg(sv[0], &msg2, 0);
562 	if (rc == -1) {
563 		test_fail("readv");
564 	}
565 
566 	if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) ||
567 					strncmp(buf4, "Time", 4)) {
568 		test_fail("readv");
569 	}
570 
571 	rc = close(sv[0]);
572 	if (rc == -1) {
573 		test_fail("close");
574 	}
575 
576 	rc = close(sv[1]);
577 	if (rc == -1) {
578 		test_fail("close");
579 	}
580 }
581 
test_scm_credentials(void)582 static void test_scm_credentials(void)
583 {
584 	int rc;
585 	int src;
586 	int dst;
587 	int one;
588 	union {
589 		struct sockcred cred;
590 		char buf[SOCKCREDSIZE(NGROUPS_MAX)];
591 	} cred;
592 	struct cmsghdr *cmsg = NULL;
593 	struct sockaddr_un addr;
594 	struct iovec iov[3];
595 	struct msghdr msg1;
596 	struct msghdr msg2;
597 	char buf1[BUFSIZE];
598 	char buf2[BUFSIZE];
599 	char buf3[BUFSIZE];
600 	char ctrl[BUFSIZE];
601 	socklen_t len, addrlen = sizeof(struct sockaddr_un);
602 
603 	debug("test_scm_credentials");
604 
605 	UNLINK(TEST_SUN_PATH);
606 	UNLINK(TEST_SUN_PATHB);
607 
608 	debug("creating src socket");
609 
610 	src = socket(PF_UNIX, SOCK_DGRAM, 0);
611 	if (src == -1) {
612 		test_fail("socket");
613 	}
614 
615 	debug("creating dst socket");
616 
617 	dst = socket(PF_UNIX, SOCK_DGRAM, 0);
618 	if (dst == -1) {
619 		test_fail("socket");
620 	}
621 
622 	debug("binding src socket");
623 
624 	memset(&addr, '\0', sizeof(struct sockaddr_un));
625 	addr.sun_family = AF_UNIX;
626 	strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1);
627 	rc = bind(src, (struct sockaddr *) &addr, addrlen);
628 	if (rc == -1) {
629 		test_fail("bind");
630 	}
631 
632 	debug("binding dst socket");
633 
634 	memset(&addr, '\0', sizeof(struct sockaddr_un));
635 	addr.sun_family = AF_UNIX;
636 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
637 
638 	rc = bind(dst, (struct sockaddr *) &addr, addrlen);
639 	if (rc == -1) {
640 		test_fail("bind");
641 	}
642 
643 	debug("request credential passing");
644 
645 	one = 1;
646 	rc = setsockopt(dst, 0, LOCAL_CREDS, &one, sizeof(one));
647 	if (rc == -1) {
648 		test_fail("setsockopt(LOCAL_CREDS)");
649 	}
650 
651 	debug("sending msg1");
652 
653 	memset(&buf1, '\0', BUFSIZE);
654 	memset(&buf2, '\0', BUFSIZE);
655 	memset(&buf3, '\0', BUFSIZE);
656 	memset(&ctrl, '\0', BUFSIZE);
657 
658 	strncpy(buf1, "Minix ", BUFSIZE-1);
659 	strncpy(buf2, "is ", BUFSIZE-1);
660 	strncpy(buf3, "great!", BUFSIZE-1);
661 
662 	iov[0].iov_base = buf1;
663 	iov[0].iov_len  = 6;
664 	iov[1].iov_base = buf2;
665 	iov[1].iov_len  = 3;
666 	iov[2].iov_base = buf3;
667 	iov[2].iov_len  = 32;
668 
669 	memset(&msg1, '\0', sizeof(struct msghdr));
670 	msg1.msg_name = &addr;
671 	msg1.msg_namelen = addrlen;
672 	msg1.msg_iov = iov;
673 	msg1.msg_iovlen = 3;
674 	msg1.msg_control = NULL;
675 	msg1.msg_controllen = 0;
676 	msg1.msg_flags = 0;
677 
678 	rc = sendmsg(src, &msg1, 0);
679 	if (rc == -1) {
680 		test_fail("sendmsg");
681 	}
682 
683 	memset(&buf1, '\0', BUFSIZE);
684 	memset(&buf2, '\0', BUFSIZE);
685 	memset(&buf3, '\0', BUFSIZE);
686 	memset(&ctrl, '\0', BUFSIZE);
687 
688 	iov[0].iov_base = buf1;
689 	iov[0].iov_len  = 9;
690 	iov[1].iov_base = buf2;
691 	iov[1].iov_len  = 32;
692 
693 	memset(&addr, '\0', sizeof(struct sockaddr_un));
694 	memset(&msg2, '\0', sizeof(struct msghdr));
695 	msg2.msg_name = &addr;
696 	msg2.msg_namelen = sizeof(struct sockaddr_un);
697 	msg2.msg_iov = iov;
698 	msg2.msg_iovlen = 2;
699 	msg2.msg_control = ctrl;
700 	msg2.msg_controllen = BUFSIZE;
701 	msg2.msg_flags = 0;
702 
703 	debug("recv msg2");
704 
705 	rc = recvmsg(dst, &msg2, 0);
706 	if (rc == -1) {
707 		test_fail("recvmsg");
708 	}
709 
710 	debug("checking results");
711 
712 	if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) {
713 		test_fail("recvmsg");
714 	}
715 
716 	/* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
717 	 * because that is what is returned by recvmsg().
718 	 */
719 	if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path,
720 					TEST_SUN_PATHB)) {
721 		test_fail("recvmsg");
722 	}
723 
724 	debug("looking for credentials");
725 
726 	len = 0;
727 
728 	memset(&cred, 'x', sizeof(cred));
729 	for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL;
730 					cmsg = CMSG_NXTHDR(&msg2, cmsg)) {
731 
732 		if (cmsg->cmsg_level == SOL_SOCKET &&
733 				cmsg->cmsg_type == SCM_CREDS) {
734 			/* Great, this alignment business!  But then at least
735 			 * give me a macro to compute the actual data length..
736 			 */
737 			len = cmsg->cmsg_len - (socklen_t)
738 			    ((char *)CMSG_DATA(cmsg) - (char *)cmsg);
739 
740 			if (len < sizeof(struct sockcred))
741 				test_fail("credentials too small");
742 			else if (len > sizeof(cred))
743 				test_fail("credentials too large");
744 			memcpy(cred.buf, CMSG_DATA(cmsg), len);
745 			break;
746 		}
747 	}
748 
749 	if (len == 0)
750 		test_fail("no credentials found");
751 
752 	if (len != SOCKCREDSIZE(cred.cred.sc_ngroups))
753 		test_fail("wrong credentials size");
754 
755 	/*
756 	 * TODO: check supplementary groups.  This whole test is pretty much
757 	 * pointless since we're running with very standard credentials anyway.
758 	 */
759 	if (cred.cred.sc_uid != getuid() ||
760 	    cred.cred.sc_euid != geteuid() ||
761 	    cred.cred.sc_gid != getgid() ||
762 	    cred.cred.sc_egid != getegid() ||
763 	    cred.cred.sc_ngroups < 0 || cred.cred.sc_ngroups > NGROUPS_MAX) {
764 		test_fail("did no receive the proper credentials");
765 	}
766 
767 	rc = close(dst);
768 	if (rc == -1) {
769 		test_fail("close");
770 	}
771 
772 	rc = close(src);
773 	if (rc == -1) {
774 		test_fail("close");
775 	}
776 
777 	UNLINK(TEST_SUN_PATH);
778 	UNLINK(TEST_SUN_PATHB);
779 }
780 
test_connect(const struct socket_test_info * info)781 static void test_connect(const struct socket_test_info *info)
782 {
783 	int i, sd, sds[2], rc;
784 
785 	/* connect() is already tested throughout test56, but
786 	 * in most cases the client and server end up on /dev/uds
787 	 * minor 0 and minor 1. This test opens some sockets first and
788 	 * then calls test_simple_client_server(). This forces the
789 	 * client and server minor numbers higher in the descriptor table.
790 	 */
791 
792 	debug("starting test_connect()");
793 
794 	sd = socket(AF_UNIX, SOCK_DGRAM, 0);
795 	if (sd == -1) {
796 		test_fail("couldn't create a socket");
797 	}
798 
799 	rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds);
800 	if (rc == -1) {
801 		test_fail("couldn't create a socketpair");
802 	}
803 
804 	for (i = 0; i < 3; i++) {
805 		test_simple_client_server(info, types[i]);
806 	}
807 
808 	rc = close(sds[1]);
809 	if (rc == -1) {
810 		test_fail("close() failed");
811 	}
812 
813 	rc = close(sds[0]);
814 	if (rc == -1) {
815 		test_fail("close() failed");
816 	}
817 
818 	rc = close(sd);
819 	if (rc == -1) {
820 		test_fail("close() failed");
821 	}
822 
823 	debug("exiting test_connect()");
824 }
825 
test_multiproc_read(void)826 static int test_multiproc_read(void)
827 {
828 /* test that when we fork() a process with an open socket descriptor,
829  * the descriptor in each process points to the same thing.
830  */
831 
832 	pid_t pid;
833 	int sds[2];
834 	int rc, status;
835 	char buf[3];
836 
837 	debug("entering test_multiproc_read()");
838 
839 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
840 	if (rc == -1) {
841 		test_fail("socketpair");
842 		return 1;
843 	}
844 
845 	memset(buf, '\0', 3);
846 
847 
848 	/* the signal handler is only used by the client, but we have to
849 	 * install it now. if we don't the server may signal the client
850 	 * before the handler is installed.
851 	 */
852 	debug("installing signal handler");
853 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
854 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
855 		return 1;
856 	}
857 
858 	debug("signal handler installed");
859 
860 	server_ready = 0;
861 
862 	pid = fork();
863 
864 	if (pid == -1) {
865 
866 		test_fail("fork");
867 		return 1;
868 
869 	} else if (pid == 0) {
870 
871 		while (server_ready == 0) {
872 			debug("waiting for SIGUSR1 from parent");
873 			sleep(1);
874 		}
875 
876 		rc = read(sds[1], buf, 2);
877 		if (rc == -1) {
878 			test_fail("read");
879 			exit(1);
880 		}
881 
882 		if (!(buf[0] == 'X' && buf[1] == '3')) {
883 			test_fail("Didn't read X3");
884 			exit(1);
885 		}
886 
887 		exit(0);
888 	} else {
889 
890 		rc = write(sds[0], "MNX3", 4);
891 		if (rc == -1) {
892 			test_fail("write");
893 		}
894 
895 		rc = read(sds[1], buf, 2);
896 		if (rc == -1) {
897 			test_fail("read");
898 		}
899 
900 		if (!(buf[0] == 'M' && buf[1] == 'N')) {
901 			test_fail("Didn't read MN");
902 		}
903 
904 		/* time to tell the client to start the test */
905 		kill(pid, SIGUSR1);
906 
907 		do {
908 			rc = waitpid(pid, &status, 0);
909 		} while (rc == -1 && errno == EINTR);
910 
911 		/* we use the exit status to get its error count */
912 		errct += WEXITSTATUS(status);
913 	}
914 
915 	return 0;
916 }
917 
test_multiproc_write(void)918 static int test_multiproc_write(void)
919 {
920 /* test that when we fork() a process with an open socket descriptor,
921  * the descriptor in each process points to the same thing.
922  */
923 
924 	pid_t pid;
925 	int sds[2];
926 	int rc, status;
927 	char buf[7];
928 
929 	debug("entering test_multiproc_write()");
930 
931 	rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds);
932 	if (rc == -1) {
933 		test_fail("socketpair");
934 		return 1;
935 	}
936 
937 	memset(buf, '\0', 7);
938 
939 
940 	/* the signal handler is only used by the client, but we have to
941 	 * install it now. if we don't the server may signal the client
942 	 * before the handler is installed.
943 	 */
944 	debug("installing signal handler");
945 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
946 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
947 		return 1;
948 	}
949 
950 	debug("signal handler installed");
951 
952 	server_ready = 0;
953 
954 	pid = fork();
955 
956 	if (pid == -1) {
957 
958 		test_fail("fork");
959 		return 1;
960 
961 	} else if (pid == 0) {
962 
963 		while (server_ready == 0) {
964 			debug("waiting for SIGUSR1 from parent");
965 			sleep(1);
966 		}
967 
968 		rc = write(sds[1], "IX3", 3);
969 		if (rc == -1) {
970 			test_fail("write");
971 			exit(1);
972 		}
973 
974 		rc = read(sds[0], buf, 6);
975 		if (rc == -1) {
976 			test_fail("read");
977 			exit(1);
978 		}
979 
980 		if (strcmp(buf, "MINIX3") != 0) {
981 			test_fail("didn't read MINIX3");
982 			exit(1);
983 		}
984 
985 		exit(0);
986 	} else {
987 
988 		rc = write(sds[1], "MIN", 3);
989 		if (rc == -1) {
990 			test_fail("write");
991 		}
992 
993 		/* time to tell the client to start the test */
994 		kill(pid, SIGUSR1);
995 
996 		do {
997 			rc = waitpid(pid, &status, 0);
998 		} while (rc == -1 && errno == EINTR);
999 
1000 		/* we use the exit status to get its error count */
1001 		errct += WEXITSTATUS(status);
1002 	}
1003 
1004 	return 0;
1005 }
1006 
test_fd_passing_child(int sd)1007 static void test_fd_passing_child(int sd)
1008 {
1009 	int fd, rc;
1010 	char x = 'x';
1011 	struct msghdr msghdr;
1012 	struct cmsghdr *cmsg;
1013 	struct iovec iov;
1014 	char buf[BUFSIZE];
1015 
1016 	memset(buf, '\0', BUFSIZE);
1017 
1018 	fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR);
1019 	if (fd == -1) {
1020 		test_fail("could not open test.txt");
1021 	}
1022 
1023 	msghdr.msg_name = NULL;
1024 	msghdr.msg_namelen = 0;
1025 
1026 	iov.iov_base = &x;
1027 	iov.iov_len = 1;
1028 	msghdr.msg_iov = &iov;
1029 	msghdr.msg_iovlen = 1;
1030 
1031 	msghdr.msg_control = buf;
1032 	msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
1033 
1034 	msghdr.msg_flags = 0;
1035 
1036 	cmsg = CMSG_FIRSTHDR(&msghdr);
1037 	cmsg->cmsg_len = CMSG_SPACE(sizeof(int));
1038 	cmsg->cmsg_level = SOL_SOCKET;
1039 	cmsg->cmsg_type = SCM_RIGHTS;
1040 
1041 	((int *) CMSG_DATA(cmsg))[0] = fd;
1042 
1043 	rc = sendmsg(sd, &msghdr, 0);
1044 	if (rc == -1) {
1045 		test_fail("could not send message");
1046 	}
1047 
1048 	memset(buf, '\0', BUFSIZE);
1049 	rc = read(sd, buf, BUFSIZE);
1050 	if (rc == -1) {
1051 		test_fail("could not read from socket");
1052 	}
1053 
1054 	if (strcmp(buf, "done") != 0) {
1055 		test_fail("we didn't read the right message");
1056 	}
1057 
1058 	memset(buf, '\0', BUFSIZE);
1059 	rc = lseek(fd, 0, SEEK_SET);
1060 	if (rc == -1) {
1061 		test_fail("could not seek to start of test.txt");
1062 	}
1063 
1064 	rc = read(fd, buf, BUFSIZE);
1065 	if (rc == -1) {
1066 		test_fail("could not read from test.txt");
1067 	}
1068 
1069 	if (strcmp(buf, MSG) != 0) {
1070 		test_fail("other process didn't write MSG to test.txt");
1071 	}
1072 
1073 	rc = close(fd);
1074 	if (rc == -1) {
1075 		test_fail("could not close test.txt");
1076 	}
1077 
1078 	rc = close(sd);
1079 	if (rc == -1) {
1080 		test_fail("could not close socket");
1081 	}
1082 
1083 	rc = unlink(TEST_TXT_FILE);
1084 	if (rc == -1) {
1085 		test_fail("could not unlink test.txt");
1086 	}
1087 
1088 	exit(errct);
1089 }
1090 
test_fd_passing_parent(int sd)1091 static void test_fd_passing_parent(int sd)
1092 {
1093 	int rc, fd;
1094 	char x;
1095 	struct msghdr msghdr;
1096 	struct cmsghdr *cmsg;
1097 	struct iovec iov;
1098 	char buf[BUFSIZE];
1099 
1100 	memset(buf, '\0', BUFSIZE);
1101 
1102 	msghdr.msg_name = NULL;
1103 	msghdr.msg_namelen = 0;
1104 
1105 	iov.iov_base = &x;
1106 	iov.iov_len = 1;
1107 	msghdr.msg_iov = &iov;
1108 	msghdr.msg_iovlen = 1;
1109 
1110 	msghdr.msg_iov = &iov;
1111 	msghdr.msg_iovlen = 1;
1112 
1113 	msghdr.msg_control = buf;
1114 	msghdr.msg_controllen = BUFSIZE;
1115 
1116 	msghdr.msg_flags = 0;
1117 
1118 	rc = recvmsg(sd, &msghdr, 0);
1119 	if (rc == -1) {
1120 		test_fail("could not recv message.");
1121 	}
1122 
1123 	cmsg = CMSG_FIRSTHDR(&msghdr);
1124 	fd = ((int *) CMSG_DATA(cmsg))[0];
1125 
1126 	rc = write(fd, MSG, strlen(MSG));
1127 	if (rc != strlen(MSG)) {
1128 		test_fail("could not write the full message to test.txt");
1129 	}
1130 
1131 	rc = close(fd);
1132 	if (rc == -1) {
1133 		test_fail("could not close test.txt");
1134 	}
1135 
1136 	memset(buf, '\0', BUFSIZE);
1137 	strcpy(buf, "done");
1138 	rc = write(sd, buf, BUFSIZE);
1139 	if (rc == -1) {
1140 		test_fail("could not write to socket");
1141 	}
1142 
1143 	rc = close(sd);
1144 	if (rc == -1) {
1145 		test_fail("could not close socket");
1146 	}
1147 }
1148 
test_permissions(void)1149 static void test_permissions(void) {
1150 	/* Test bind and connect for permission verification
1151 	 *
1152 	 * After creating a UDS socket we change user credentials. At that
1153 	 * point we should not be allowed to bind or connect to the UDS socket
1154 	 */
1155 
1156 	pid_t pid;
1157 	int sd, rc, status;
1158 	struct sockaddr_un addr;
1159 
1160 	memset(&addr, '\0', sizeof(struct sockaddr_un));
1161 	addr.sun_family = AF_UNIX;
1162 	strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1);
1163 
1164 	UNLINK(TEST_SUN_PATH);
1165 
1166 	pid = fork();
1167 	if (pid < 0) test_fail("unable to fork");
1168 	else if (pid == 0) {
1169 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1170 		if (setuid(999) != 0) test_fail("unable to chance uid");
1171 		rc = bind(sd, (struct sockaddr *) &addr,
1172 				 sizeof(struct sockaddr_un));
1173 		if (rc != -1) {
1174 			test_fail("bind() should not have worked");
1175 		}
1176 		exit(errct);
1177 	} else {
1178 		rc = waitpid(pid, &status, 0);
1179 		errct += WEXITSTATUS(status);
1180 	}
1181 
1182 	/* the signal handler is only used by the client, but we have to
1183 	 * install it now. if we don't the server may signal the client
1184 	 * before the handler is installed.
1185 	 */
1186 	debug("installing signal handler");
1187 	if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) {
1188 		test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1189 	}
1190 
1191 	debug("signal handler installed");
1192 
1193 	server_ready = 0;
1194 
1195 	pid = fork();
1196 	if (pid < 0) test_fail("unable to fork");
1197 	else if (pid == 0) {
1198 		while (server_ready == 0) {
1199 			debug("[client] waiting for the server to signal");
1200 			sleep(1);
1201 		}
1202 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1203 		if (setuid(999) != 0) test_fail("unable to chance uid");
1204 		rc = connect(sd, (struct sockaddr *) &addr,
1205 						sizeof(struct sockaddr_un));
1206 		if (rc != -1)
1207 			test_fail("connect should not have worked");
1208 		exit(errct);
1209 	} else {
1210 		SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
1211 		rc = bind(sd, (struct sockaddr *) &addr,
1212 				 sizeof(struct sockaddr_un));
1213 		if (rc == -1) {
1214 			test_fail("bind() should have worked");
1215 		}
1216 
1217 		rc = listen(sd, 8);
1218 		if (rc == -1) {
1219 			test_fail("listen(sd, 8) should have worked");
1220 		}
1221 		kill(pid, SIGUSR1);
1222 		sleep(1);
1223 		CLOSE(sd);
1224 
1225 		rc = waitpid(pid, &status, 0);
1226 		errct += WEXITSTATUS(status);
1227 	}
1228 
1229 	UNLINK(TEST_SUN_PATH);
1230 }
1231 
test_fd_passing(void)1232 static void test_fd_passing(void) {
1233 	int status;
1234 	int sv[2];
1235 	pid_t pid;
1236 	int rc;
1237 
1238 	rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
1239 	if (rc == -1) {
1240 		test_fail("socketpair failed");
1241 	}
1242 
1243 	pid = fork();
1244 	if (pid == -1) {
1245 		test_fail("fork() failed");
1246 
1247 		rc = close(sv[0]);
1248 		if (rc == -1) {
1249 			test_fail("could not close sv[0]");
1250 		}
1251 
1252 		rc = close(sv[1]);
1253 		if (rc == -1) {
1254 			test_fail("could not close sv[1]");
1255 		}
1256 
1257 		exit(0);
1258 	} else if (pid == 0) {
1259 		rc = close(sv[0]);
1260 		if (rc == -1) {
1261 			test_fail("could not close sv[0]");
1262 		}
1263 
1264 		test_fd_passing_child(sv[1]);
1265 		test_fail("should never get here");
1266 		exit(1);
1267 	} else {
1268 		rc = close(sv[1]);
1269 		if (rc == -1) {
1270 			test_fail("could not close sv[1]");
1271 		}
1272 
1273 		test_fd_passing_parent(sv[0]);
1274 
1275 		/* wait for client to exit */
1276 		do {
1277 			errno = 0;
1278 			rc = waitpid(pid, &status, 0);
1279 		} while (rc == -1 && errno == EINTR);
1280 
1281 		/* we use the exit status to get its error count */
1282 		errct += WEXITSTATUS(status);
1283 	}
1284 }
1285 
test_select(void)1286 static void test_select(void)
1287 {
1288 	int nfds = -1;
1289 	int socks[2];
1290 	fd_set readfds, writefds;
1291 	struct timeval tv;
1292 	int res = 0;
1293 	char buf[1];
1294 
1295 	FD_ZERO(&readfds);
1296 	FD_ZERO(&writefds);
1297 
1298 	tv.tv_sec = 2;
1299 	tv.tv_usec = 0;	/* 2 sec time out */
1300 
1301 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1302 		test_fail("Can't open socket pair.");
1303 	}
1304 	FD_SET(socks[0], &readfds);
1305 	nfds = socks[0] + 1;
1306 
1307 	/* Close the write end of the socket to generate EOF on read end */
1308 	if ((res = shutdown(socks[1], SHUT_WR)) != 0) {
1309 		test_fail("shutdown failed\n");
1310 	}
1311 
1312 	res = select(nfds, &readfds, NULL, NULL, &tv);
1313 	if (res != 1) {
1314 		test_fail("select should've returned 1 ready fd\n");
1315 	}
1316 	if (!(FD_ISSET(socks[0], &readfds))) {
1317 		test_fail("The server didn't respond within 2 seconds");
1318 	}
1319 	/* Now try to read from empty, closed pipe */
1320 	if (read(socks[0], buf, sizeof(buf)) != 0) {
1321 		test_fail("reading from empty, closed pipe should return EOF");
1322 	}
1323 
1324 	close(socks[0]);
1325 
1326 	/* Try again the other way around: create a socketpair, close the
1327 	 * read end, and try to write. This should cause an EPIPE */
1328 
1329 	tv.tv_sec = 2;
1330 	tv.tv_usec = 0;	/* 2 sec time out */
1331 
1332 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1333 		test_fail("Can't open socket pair.");
1334 	}
1335 	FD_SET(socks[1], &writefds);
1336 	nfds = socks[1] + 1;
1337 
1338 	/* kill the read end of the socket to generate EPIPE on write end */
1339 	if ((res = shutdown(socks[0], SHUT_RD)) != 0) {
1340 		test_fail("shutdown failed\n");
1341 	}
1342 
1343 	res = select(nfds, NULL, &writefds, NULL, &tv);
1344 	if (res != 1) {
1345 		test_fail("select should've returned 1 ready fd\n");
1346 	}
1347 	if (!(FD_ISSET(socks[1], &writefds))) {
1348 		test_fail("The server didn't respond within 2 seconds");
1349 	}
1350 
1351 	/* Now try to write to closed pipe */
1352 	errno = 0;
1353 	if ((res = write(socks[1], buf, sizeof(buf))) != -1) {
1354 		printf("write res = %d\n", res);
1355 		test_fail("writing to empty, closed pipe should fail");
1356 	}
1357 	if (errno != EPIPE) {
1358 		printf("errno = %d\n", errno);
1359 		test_fail("writing to closed pipe should return EPIPE\n");
1360 	}
1361 
1362 	close(socks[1]);
1363 }
1364 
test_select_close(void)1365 static void test_select_close(void)
1366 {
1367 	int res, socks[2];
1368 	fd_set readfds;
1369 	struct timeval tv;
1370 
1371 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1372 		test_fail("Can't open socket pair.");
1373 	}
1374 
1375 	switch (fork()) {
1376 	case 0:
1377 		sleep(1);
1378 
1379 		exit(0);
1380 	case -1:
1381 		test_fail("Can't fork.");
1382 	default:
1383 		break;
1384 	}
1385 
1386 	close(socks[1]);
1387 
1388 	FD_ZERO(&readfds);
1389 	FD_SET(socks[0], &readfds);
1390 	tv.tv_sec = 2;
1391 	tv.tv_usec = 0;	/* 2 sec time out */
1392 
1393 	res = select(socks[0] + 1, &readfds, NULL, NULL, &tv);
1394 	if (res != 1) {
1395 		test_fail("select should've returned 1 ready fd\n");
1396 	}
1397 	if (!(FD_ISSET(socks[0], &readfds))) {
1398 		test_fail("The server didn't respond within 2 seconds");
1399 	}
1400 
1401 	wait(NULL);
1402 
1403 	close(socks[0]);
1404 }
1405 
test_fchmod(void)1406 static void test_fchmod(void)
1407 {
1408 	int socks[2];
1409 	struct stat st1, st2;
1410 
1411 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) {
1412 		test_fail("Can't open socket pair.");
1413 	}
1414 
1415 	if (fstat(socks[0], &st1) < 0 || fstat(socks[1], &st2) < 0) {
1416 		test_fail("fstat failed.");
1417 	}
1418 
1419 	if ((st1.st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR &&
1420 		(st2.st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR) {
1421 		test_fail("fstat failed.");
1422 	}
1423 
1424 	if (fchmod(socks[0], S_IRUSR) < 0 ||
1425                     fstat(socks[0], &st1) < 0 ||
1426                     (st1.st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR) {
1427 		test_fail("fchmod/fstat mode set/check failed (1).");
1428 	}
1429 
1430 	if (fchmod(socks[1], S_IWUSR) < 0 || fstat(socks[1], &st2) < 0 ||
1431                     (st2.st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR) {
1432 		test_fail("fchmod/fstat mode set/check failed (2).");
1433 	}
1434 
1435 	close(socks[0]);
1436 	close(socks[1]);
1437 }
1438 
1439 /*
1440  * Test various aspects related to the socket files on the file system.
1441  * This subtest is woefully incomplete and currently only attempts to test
1442  * aspects that have recently been affected by code changes.  In the future,
1443  * there should be tests for the entire range of file system path and access
1444  * related error codes (TODO).
1445  */
1446 static void
test_file(void)1447 test_file(void)
1448 {
1449 	struct sockaddr_un addr, saddr, saddr2;
1450 	char buf[1];
1451 	socklen_t len;
1452 	struct stat st;
1453 	mode_t omask;
1454 	int sd, sd2, csd, fd;
1455 
1456 	/*
1457 	 * If the provided socket path exists on the file system, the bind(2)
1458 	 * call must fail, regardless of whether there is a socket that is
1459 	 * bound to that address.
1460 	 */
1461 	UNLINK(TEST_SUN_PATH);
1462 
1463 	memset(&addr, 0, sizeof(addr));
1464 	addr.sun_family = AF_UNIX;
1465 	strlcpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path));
1466 
1467 	if ((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1468 		test_fail("Can't open socket");
1469 	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1470 		test_fail("Can't bind socket");
1471 
1472 	if ((sd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1473 		test_fail("Can't open socket");
1474 	if (bind(sd2, (struct sockaddr *)&addr, sizeof(addr)) != -1)
1475 		test_fail("Binding socket unexpectedly succeeded");
1476 	if (errno != EADDRINUSE)
1477 		test_fail("Binding socket failed with wrong error");
1478 
1479 	CLOSE(sd);
1480 
1481 	if (bind(sd2, (struct sockaddr *)&addr, sizeof(addr)) != -1)
1482 		test_fail("Binding socket unexpectedly succeeded");
1483 	if (errno != EADDRINUSE)
1484 		test_fail("Binding socket failed with wrong error");
1485 
1486 	CLOSE(sd2);
1487 
1488 	UNLINK(TEST_SUN_PATH);
1489 
1490 	/*
1491 	 * If the socket is removed from the file system while there is still a
1492 	 * socket bound to it, it should be possible to bind a new socket to
1493 	 * the address.  The old socket should then become unreachable in terms
1494 	 * of connections and data directed to the address, even though it
1495 	 * should still appear to be bound to the same address.
1496 	 */
1497 	if ((sd = socket(PF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
1498 		test_fail("Can't open socket");
1499 	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1500 		test_fail("Can't bind socket");
1501 	memset(&saddr, 0, sizeof(saddr));
1502 	len = sizeof(saddr);
1503 	if (getsockname(sd, (struct sockaddr *)&saddr, &len) != 0)
1504 		test_fail("Can't get socket address");
1505 
1506 	if ((csd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1507 		test_fail("Can't open client socket");
1508 
1509 	memset(buf, 'X', sizeof(buf));
1510 	if (sendto(csd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
1511 	    sizeof(addr)) != sizeof(buf))
1512 		test_fail("Can't send to socket");
1513 	if (recvfrom(sd, buf, sizeof(buf), 0, NULL, 0) != sizeof(buf))
1514 		test_fail("Can't receive from socket");
1515 	if (buf[0] != 'X')
1516 		test_fail("Transmission failure");
1517 
1518 	if (unlink(TEST_SUN_PATH) != 0)
1519 		test_fail("Can't unlink socket");
1520 
1521 	if ((sd2 = socket(PF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
1522 		test_fail("Can't open socket");
1523 	if (bind(sd2, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1524 		test_fail("Can't bind socket");
1525 	memset(&saddr2, 0, sizeof(saddr2));
1526 	len = sizeof(saddr2);
1527 	if (getsockname(sd2, (struct sockaddr *)&saddr2, &len) != 0)
1528 		test_fail("Can't get socket address");
1529 	if (memcmp(&saddr, &saddr2, sizeof(saddr)))
1530 		test_fail("Unexpected socket address");
1531 
1532 	memset(buf, 'Y', sizeof(buf));
1533 	if (sendto(csd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
1534 	    sizeof(addr)) != sizeof(buf))
1535 		test_fail("Can't send to socket");
1536 	if (recvfrom(sd, buf, sizeof(buf), 0, NULL, 0) != -1)
1537 		test_fail("Unexpectedly received from old socket");
1538 	if (errno != EWOULDBLOCK)
1539 		test_fail("Wrong receive failure from old socket");
1540 	if (recvfrom(sd2, buf, sizeof(buf), 0, NULL, 0) != sizeof(buf))
1541 		test_fail("Can't receive from new socket");
1542 	if (buf[0] != 'Y')
1543 		test_fail("Transmission failure");
1544 
1545 	len = sizeof(saddr2);
1546 	if (getsockname(sd, (struct sockaddr *)&saddr2, &len) != 0)
1547 		test_fail("Can't get old socket address");
1548 	if (memcmp(&saddr, &saddr2, sizeof(saddr)))
1549 		test_fail("Unexpected old socket address");
1550 
1551 	if (unlink(TEST_SUN_PATH) != 0)
1552 		test_fail("Can't unlink socket");
1553 
1554 	CLOSE(sd);
1555 	CLOSE(sd2);
1556 	CLOSE(csd);
1557 
1558 	/*
1559 	 * If the socket path identifies a file that is not a socket, bind(2)
1560 	 * should still fail with EADDRINUSE, but connect(2) and sendto(2)
1561 	 * should fail with ENOTSOCK (the latter is not specified by POSIX, so
1562 	 * we follow NetBSD here).
1563 	 */
1564 	if ((fd = open(TEST_SUN_PATH, O_WRONLY | O_CREAT | O_EXCL, 0700)) < 0)
1565 		test_fail("Can't create regular file");
1566 	CLOSE(fd);
1567 
1568 	if ((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1569 		test_fail("Can't open socket");
1570 	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != -1)
1571 		test_fail("Binding socket unexpectedly succeeded");
1572 	if (errno != EADDRINUSE)
1573 		test_fail("Binding socket failed with wrong error");
1574 	if (sendto(sd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
1575 	    sizeof(addr)) != -1)
1576 		test_fail("Sending to socket unexpectedly succeeded");
1577 	if (errno != ENOTSOCK)
1578 		test_fail("Sending to socket failed with wrong error");
1579 	CLOSE(sd);
1580 
1581 	if ((sd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
1582 		test_fail("Can't open socket");
1583 	if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) != -1)
1584 		test_fail("Connecting socket unexpectedly succeeded");
1585 	if (errno != ENOTSOCK)
1586 		test_fail("Connecting socket failed with wrong error");
1587 	CLOSE(sd);
1588 
1589 	UNLINK(TEST_SUN_PATH);
1590 
1591 	/*
1592 	 * The created socket file should have an access mode of 0777 corrected
1593 	 * with the calling process's file mode creation mask.
1594 	 */
1595 	omask = umask(045123);
1596 
1597 	if ((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1598 		test_fail("Can't open socket");
1599 	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1600 		test_fail("Can't bind socket");
1601 
1602 	if (stat(TEST_SUN_PATH, &st) != 0)
1603 		test_fail("Can't stat socket");
1604 	if (!S_ISSOCK(st.st_mode))
1605 		test_fail("File is not a socket");
1606 	if ((st.st_mode & ALLPERMS) != (ACCESSPERMS & ~0123))
1607 		test_fail("Unexpected file permission mask");
1608 
1609 	CLOSE(sd);
1610 	UNLINK(TEST_SUN_PATH);
1611 
1612 	umask(omask);
1613 
1614 	/*
1615 	 * Only socket(2), socketpair(2), and accept(2) may be used to obtain
1616 	 * new file descriptors to sockets (or "sockets"); open(2) on a socket
1617 	 * file is expected to fail with EOPNOTSUPP (Austin Group Issue #943),
1618 	 * regardless of whether the socket is in use.
1619 	 */
1620 	if ((sd = socket(PF_UNIX, SOCK_DGRAM, 0)) == -1)
1621 		test_fail("Can't open socket");
1622 	if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
1623 		test_fail("Can't bind socket");
1624 
1625 	if (open(TEST_SUN_PATH, O_RDWR) != -1)
1626 		test_fail("Unexpectedly opened socket file");
1627 	if (errno != EOPNOTSUPP)
1628 		test_fail("Open failed with wrong error");
1629 
1630 	CLOSE(sd);
1631 
1632 	if (open(TEST_SUN_PATH, O_RDONLY) != -1)
1633 		test_fail("Unexpectedly opened socket file");
1634 	if (errno != EOPNOTSUPP)
1635 		test_fail("Open failed with wrong error");
1636 
1637 	UNLINK(TEST_SUN_PATH);
1638 }
1639 
main(int argc,char * argv[])1640 int main(int argc, char *argv[])
1641 {
1642 	int i;
1643 	struct sockaddr_un clientaddr = {
1644 		.sun_family = AF_UNIX,
1645 		.sun_path = TEST_SUN_PATH,
1646 	};
1647 	struct sockaddr_un clientaddr2 = {
1648 		.sun_family = AF_UNIX,
1649 		.sun_path = TEST_SUN_PATHB,
1650 	};
1651 	struct sockaddr_un clientaddrsym = {
1652 		.sun_family = AF_UNIX,
1653 		.sun_path = TEST_SYM_A,
1654 	};
1655 	const struct socket_test_info info = {
1656 		.clientaddr               = (struct sockaddr *) &clientaddr,
1657 		.clientaddrlen            = sizeof(clientaddr),
1658 		.clientaddr2              = (struct sockaddr *) &clientaddr2,
1659 		.clientaddr2len           = sizeof(clientaddr2),
1660 		.clientaddrsym            = (struct sockaddr *) &clientaddrsym,
1661 		.clientaddrsymlen         = sizeof(clientaddrsym),
1662 		.domain                   = PF_UNIX,
1663 		.expected_rcvbuf          = 32768 - 5, /* no constants: */
1664 		.expected_sndbuf          = 32768 - 5, /* UDS internals */
1665 		.serveraddr               = (struct sockaddr *) &clientaddr,
1666 		.serveraddrlen            = sizeof(clientaddr),
1667 		.serveraddr2              = (struct sockaddr *) &clientaddr2,
1668 		.serveraddr2len           = sizeof(clientaddr2),
1669 		.type                     = SOCK_STREAM,
1670 		.types                    = types,
1671 		.typecount                = 3,
1672 		.callback_check_sockaddr  = callback_check_sockaddr,
1673 		.callback_cleanup         = callback_cleanup,
1674 		.callback_xfer_prepclient = callback_xfer_prepclient,
1675 		.callback_xfer_peercred   = callback_xfer_peercred,
1676 		.callback_set_listen_opt  = callback_set_listen_opt,
1677 	};
1678 
1679 	debug("entering main()");
1680 
1681 	start(56);
1682 
1683 	/* This test was written before UDS started supporting SIGPIPE. */
1684 	signal(SIGPIPE, SIG_IGN);
1685 
1686 	test_socket(&info);
1687 	test_bind(&info);
1688 	test_bind_unix();
1689 	test_listen(&info);
1690 	test_getsockname(&info);
1691 	test_header();
1692 	test_shutdown(&info);
1693 	test_close(&info);
1694 	test_permissions();
1695 	test_dup(&info);
1696 	test_dup2(&info);
1697 	test_socketpair();
1698 	test_shutdown(&info);
1699 	test_read(&info);
1700 	test_write(&info);
1701 	test_sockopts(&info);
1702 	test_ucred();
1703 	test_xfer(&info);
1704 
1705 	for (i = 0; i < 3; i++) {
1706 		test_simple_client_server(&info, types[i]);
1707 		if (types[i] != SOCK_DGRAM) test_vectorio(types[i]);
1708 		if (types[i] != SOCK_DGRAM) test_msg(types[i]);
1709 	}
1710 
1711 	test_abort_client_server(&info, 1);
1712 	test_abort_client_server(&info, 2);
1713 	test_msg_dgram(&info);
1714 	test_connect(&info);
1715 	test_multiproc_read();
1716 	test_multiproc_write();
1717 	test_scm_credentials();
1718 	test_fd_passing();
1719 	test_select();
1720 	test_select_close();
1721 	test_fchmod();
1722 	test_nonblock(&info);
1723 	test_connect_nb(&info);
1724 	test_intr(&info);
1725 	test_connect_close(&info);
1726 	test_listen_close(&info);
1727 	test_listen_close_nb(&info);
1728 	test_file();
1729 
1730 	quit();
1731 
1732 	return -1;	/* we should never get here */
1733 }
1734