2 * Test Program for Unix Domain Sockets
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.
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().
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()
46 #include <sys/socket.h>
47 #include <sys/ucred.h>
50 #include <sys/types.h>
57 /* Maximum number of errors that we'll allow to occur before this test
58 * program gives us and quits.
62 #include "common-socket.h"
65 /* Use the common testing code instead of reinventing the wheel. */
67 /* path of the unix domain socket */
68 #define TEST_SUN_PATH "test.sock"
69 #define TEST_SUN_PATHB "testb.sock"
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"
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"
79 /* socket types supported */
80 static int types
[3] = {SOCK_STREAM
, SOCK_SEQPACKET
, SOCK_DGRAM
};
82 static void test_header(void)
84 struct sockaddr_un sun
;
85 debug("entering test_header()");
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';
93 if (SUN_LEN(&sun
) != 5) {
94 test_fail("SUN_LEN(&sun) should be 5");
97 if (PF_UNIX
!= PF_LOCAL
|| PF_UNIX
!= AF_UNIX
) {
98 test_fail("PF_UNIX, PF_LOCAL and AF_UNIX");
102 static void test_socketpair(void)
105 struct sockaddr_un addr
;
106 int socket_vector
[2];
110 debug("entering test_socketpair()");
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);
117 debug("Testing socketpair() success");
119 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, socket_vector
);
121 test_fail("socketpair() should have worked");
124 debug("Testing a simple read/write using sockets from socketpair()");
125 memset(buf
, '\0', sizeof(buf
));
127 strncpy(buf
, "Howdy Partner", sizeof(buf
) - 1);
129 rc
= write(socket_vector
[0], buf
, sizeof(buf
));
131 test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly");
134 memset(buf
, '\0', sizeof(buf
));
136 rc
= read(socket_vector
[1], buf
, sizeof(buf
));
138 test_fail("read() failed unexpectedly");
141 if (strncmp(buf
, "Howdy Partner", strlen("Howdy Partner")) != 0) {
142 test_fail("We did not read what we wrote");
145 CLOSE(socket_vector
[0]);
146 CLOSE(socket_vector
[1]);
148 debug("Test socketpair() with all FDs open by this process");
150 for (i
= 3; i
< getdtablesize(); i
++) {
151 rc
= open("/dev/null", O_RDONLY
);
153 test_fail("we couldn't open /dev/null for read");
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");
162 for (i
= 3; i
< getdtablesize(); i
++) {
166 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 4, socket_vector
);
167 if (!(rc
== -1 && errno
== EPROTONOSUPPORT
)) {
168 test_fail("socketpair() should have failed");
171 debug("leaving test_socketpair()");
174 static void test_ucred(void)
176 struct unpcbid credentials
;
177 socklen_t ucred_length
;
178 uid_t euid
= geteuid();
179 gid_t egid
= getegid();
183 debug("Test peer credentials");
185 ucred_length
= sizeof(credentials
);
187 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sv
);
189 test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed");
192 memset(&credentials
, '\0', ucred_length
);
193 rc
= getsockopt(sv
[0], 0, LOCAL_PEEREID
, &credentials
,
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");
206 rc
= getpeereid(sv
[0], &euid
, &egid
);
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");
218 static void callback_check_sockaddr(const struct sockaddr
*sockaddr
,
219 socklen_t sockaddrlen
, const char *callname
, int addridx
) {
222 const struct sockaddr_un
*sockaddr_un
=
223 (const struct sockaddr_un
*) sockaddr
;
226 case 1: path
= TEST_SUN_PATH
; break;
227 case 2: path
= TEST_SUN_PATHB
; break;
229 fprintf(stderr
, "error: invalid addridx %d in "
230 "callback_check_sockaddr\n", addridx
);
234 if (!(sockaddr_un
->sun_family
== AF_UNIX
&&
235 strncmp(sockaddr_un
->sun_path
,
237 sizeof(sockaddr_un
->sun_path
) - 1) == 0)) {
239 snprintf(buf
, sizeof(buf
), "%s() didn't return the right addr",
242 fprintf(stderr
, "exp: '%s' | got: '%s'\n", path
,
243 sockaddr_un
->sun_path
);
247 static void callback_cleanup(void) {
248 UNLINK(TEST_SUN_PATH
);
249 UNLINK(TEST_SUN_PATHB
);
254 static void test_bind_unix(void)
256 struct sockaddr_un addr
;
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);
266 debug("Test bind() with an empty sun_path");
268 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
269 memset(addr
.sun_path
, '\0', sizeof(addr
.sun_path
));
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");
278 debug("Test bind() using a symlink loop");
280 UNLINK(TEST_SUN_PATH
);
284 SYMLINK(TEST_SYM_B
, TEST_SYM_A
);
286 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
288 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
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");
296 SYMLINK(TEST_SYM_A
, TEST_SYM_B
);
298 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
300 strncpy(addr
.sun_path
, TEST_SYM_A
, sizeof(addr
.sun_path
) - 1);
301 strlcat(addr
.sun_path
, "/x", sizeof(addr
.sun_path
));
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");
309 UNLINK(TEST_SUN_PATH
);
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
) +
325 test_fail("bind() should have worked");
330 debug("leaving test_bind_unix()");
333 static void callback_xfer_prepclient(void) {
334 debug("Creating symlink to TEST_SUN_PATH");
336 SYMLINK(TEST_SUN_PATH
, TEST_SYM_A
);
339 static void callback_xfer_peercred(int sd
) {
340 struct unpcbid credentials
;
342 socklen_t ucred_length
;
344 ucred_length
= sizeof(credentials
);
346 debug("Test obtaining the peer credentials");
348 memset(&credentials
, '\0', ucred_length
);
349 rc
= getsockopt(sd
, 0, LOCAL_PEEREID
, &credentials
, &ucred_length
);
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");
363 callback_set_listen_opt(int sd
)
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.
379 if (setsockopt(sd
, 0, LOCAL_CONNWAIT
, &val
, sizeof(val
)) != 0)
380 test_fail("setsockopt(LOCAL_CONNWAIT)");
383 static void test_vectorio(int type
)
391 char buf4
[BUFSIZE
*3];
392 const struct iovec
*iovp
= iov
;
394 debug("begin vectorio tests");
396 memset(buf1
, '\0', BUFSIZE
);
397 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
399 memset(buf2
, '\0', BUFSIZE
);
400 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
402 memset(buf3
, '\0', BUFSIZE
);
404 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
406 test_fail("socketpair");
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
;
416 rc
= writev(sv
[0], iovp
, 3);
421 memset(buf4
, '\0', BUFSIZE
*3);
423 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
428 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
429 test_fail("the string we read was not 'HELLO WORLD'");
432 memset(buf1
, '\0', BUFSIZE
);
433 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
435 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
440 memset(buf2
, '\0', BUFSIZE
);
441 memset(buf3
, '\0', BUFSIZE
);
442 memset(buf4
, '\0', BUFSIZE
*3);
444 iov
[0].iov_base
= buf2
;
446 iov
[1].iov_base
= buf3
;
448 iov
[2].iov_base
= buf4
;
451 rc
= readv(sv
[0], iovp
, 3);
456 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
457 strncmp(buf4
, "Time", 4)) {
471 debug("done vector io tests");
474 static void test_msg(int type
)
484 char buf4
[BUFSIZE
*3];
486 debug("begin sendmsg/recvmsg tests");
488 memset(buf1
, '\0', BUFSIZE
);
489 strncpy(buf1
, "HELLO ", BUFSIZE
- 1);
491 memset(buf2
, '\0', BUFSIZE
);
492 strncpy(buf2
, "WORLD", BUFSIZE
- 1);
494 memset(buf3
, '\0', BUFSIZE
);
496 rc
= socketpair(PF_UNIX
, type
, 0, sv
);
498 test_fail("socketpair");
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
;
508 memset(&msg1
, '\0', sizeof(struct msghdr
));
509 msg1
.msg_name
= NULL
;
510 msg1
.msg_namelen
= 0;
513 msg1
.msg_control
= NULL
;
514 msg1
.msg_controllen
= 0;
517 rc
= sendmsg(sv
[0], &msg1
, 0);
522 memset(buf4
, '\0', BUFSIZE
*3);
524 rc
= read(sv
[1], buf4
, BUFSIZE
*3);
529 if (strncmp(buf4
, "HELLO WORLD", strlen("HELLO WORLD"))) {
530 test_fail("the string we read was not 'HELLO WORLD'");
533 memset(buf1
, '\0', BUFSIZE
);
534 strncpy(buf1
, "Unit Test Time", BUFSIZE
- 1);
536 rc
= write(sv
[1], buf1
, strlen(buf1
) + 1);
541 memset(buf2
, '\0', BUFSIZE
);
542 memset(buf3
, '\0', BUFSIZE
);
543 memset(buf4
, '\0', BUFSIZE
*3);
545 iov
[0].iov_base
= buf2
;
547 iov
[1].iov_base
= buf3
;
549 iov
[2].iov_base
= buf4
;
552 memset(&msg2
, '\0', sizeof(struct msghdr
));
553 msg2
.msg_name
= NULL
;
554 msg2
.msg_namelen
= 0;
557 msg2
.msg_control
= NULL
;
558 msg2
.msg_controllen
= 0;
561 rc
= recvmsg(sv
[0], &msg2
, 0);
566 if (strncmp(buf2
, "Unit ", 5) || strncmp(buf3
, "Test ", 5) ||
567 strncmp(buf4
, "Time", 4)) {
582 static void test_scm_credentials(void)
589 struct sockcred cred
;
590 char buf
[SOCKCREDSIZE(NGROUPS_MAX
)];
592 struct cmsghdr
*cmsg
= NULL
;
593 struct sockaddr_un addr
;
601 socklen_t len
, addrlen
= sizeof(struct sockaddr_un
);
603 debug("test_scm_credentials");
605 UNLINK(TEST_SUN_PATH
);
606 UNLINK(TEST_SUN_PATHB
);
608 debug("creating src socket");
610 src
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
615 debug("creating dst socket");
617 dst
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
622 debug("binding src socket");
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
);
632 debug("binding dst socket");
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);
638 rc
= bind(dst
, (struct sockaddr
*) &addr
, addrlen
);
643 debug("request credential passing");
646 rc
= setsockopt(dst
, 0, LOCAL_CREDS
, &one
, sizeof(one
));
648 test_fail("setsockopt(LOCAL_CREDS)");
651 debug("sending msg1");
653 memset(&buf1
, '\0', BUFSIZE
);
654 memset(&buf2
, '\0', BUFSIZE
);
655 memset(&buf3
, '\0', BUFSIZE
);
656 memset(&ctrl
, '\0', BUFSIZE
);
658 strncpy(buf1
, "Minix ", BUFSIZE
-1);
659 strncpy(buf2
, "is ", BUFSIZE
-1);
660 strncpy(buf3
, "great!", BUFSIZE
-1);
662 iov
[0].iov_base
= buf1
;
664 iov
[1].iov_base
= buf2
;
666 iov
[2].iov_base
= buf3
;
669 memset(&msg1
, '\0', sizeof(struct msghdr
));
670 msg1
.msg_name
= &addr
;
671 msg1
.msg_namelen
= addrlen
;
674 msg1
.msg_control
= NULL
;
675 msg1
.msg_controllen
= 0;
678 rc
= sendmsg(src
, &msg1
, 0);
680 test_fail("sendmsg");
683 memset(&buf1
, '\0', BUFSIZE
);
684 memset(&buf2
, '\0', BUFSIZE
);
685 memset(&buf3
, '\0', BUFSIZE
);
686 memset(&ctrl
, '\0', BUFSIZE
);
688 iov
[0].iov_base
= buf1
;
690 iov
[1].iov_base
= buf2
;
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
);
699 msg2
.msg_control
= ctrl
;
700 msg2
.msg_controllen
= BUFSIZE
;
705 rc
= recvmsg(dst
, &msg2
, 0);
707 test_fail("recvmsg");
710 debug("checking results");
712 if (strncmp(buf1
, "Minix is ", 9) || strncmp(buf2
, "great!", 6)) {
713 test_fail("recvmsg");
716 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock"
717 * because that is what is returned by recvmsg().
719 if (addr
.sun_family
!= AF_UNIX
|| strcmp(addr
.sun_path
,
721 test_fail("recvmsg");
724 debug("looking for credentials");
728 memset(&cred
, 'x', sizeof(cred
));
729 for (cmsg
= CMSG_FIRSTHDR(&msg2
); cmsg
!= NULL
;
730 cmsg
= CMSG_NXTHDR(&msg2
, cmsg
)) {
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..
737 len
= cmsg
->cmsg_len
- (socklen_t
)
738 ((char *)CMSG_DATA(cmsg
) - (char *)cmsg
);
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
);
750 test_fail("no credentials found");
752 if (len
!= SOCKCREDSIZE(cred
.cred
.sc_ngroups
))
753 test_fail("wrong credentials size");
756 * TODO: check supplementary groups. This whole test is pretty much
757 * pointless since we're running with very standard credentials anyway.
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");
777 UNLINK(TEST_SUN_PATH
);
778 UNLINK(TEST_SUN_PATHB
);
781 static void test_connect(const struct socket_test_info
*info
)
783 int i
, sd
, sds
[2], rc
;
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.
792 debug("starting test_connect()");
794 sd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
796 test_fail("couldn't create a socket");
799 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sds
);
801 test_fail("couldn't create a socketpair");
804 for (i
= 0; i
< 3; i
++) {
805 test_simple_client_server(info
, types
[i
]);
810 test_fail("close() failed");
815 test_fail("close() failed");
820 test_fail("close() failed");
823 debug("exiting test_connect()");
826 static int test_multiproc_read(void)
828 /* test that when we fork() a process with an open socket descriptor,
829 * the descriptor in each process points to the same thing.
837 debug("entering test_multiproc_read()");
839 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
841 test_fail("socketpair");
845 memset(buf
, '\0', 3);
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.
852 debug("installing signal handler");
853 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
854 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
858 debug("signal handler installed");
869 } else if (pid
== 0) {
871 while (server_ready
== 0) {
872 debug("waiting for SIGUSR1 from parent");
876 rc
= read(sds
[1], buf
, 2);
882 if (!(buf
[0] == 'X' && buf
[1] == '3')) {
883 test_fail("Didn't read X3");
890 rc
= write(sds
[0], "MNX3", 4);
895 rc
= read(sds
[1], buf
, 2);
900 if (!(buf
[0] == 'M' && buf
[1] == 'N')) {
901 test_fail("Didn't read MN");
904 /* time to tell the client to start the test */
908 rc
= waitpid(pid
, &status
, 0);
909 } while (rc
== -1 && errno
== EINTR
);
911 /* we use the exit status to get its error count */
912 errct
+= WEXITSTATUS(status
);
918 static int test_multiproc_write(void)
920 /* test that when we fork() a process with an open socket descriptor,
921 * the descriptor in each process points to the same thing.
929 debug("entering test_multiproc_write()");
931 rc
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, sds
);
933 test_fail("socketpair");
937 memset(buf
, '\0', 7);
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.
944 debug("installing signal handler");
945 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
946 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
950 debug("signal handler installed");
961 } else if (pid
== 0) {
963 while (server_ready
== 0) {
964 debug("waiting for SIGUSR1 from parent");
968 rc
= write(sds
[1], "IX3", 3);
974 rc
= read(sds
[0], buf
, 6);
980 if (strcmp(buf
, "MINIX3") != 0) {
981 test_fail("didn't read MINIX3");
988 rc
= write(sds
[1], "MIN", 3);
993 /* time to tell the client to start the test */
997 rc
= waitpid(pid
, &status
, 0);
998 } while (rc
== -1 && errno
== EINTR
);
1000 /* we use the exit status to get its error count */
1001 errct
+= WEXITSTATUS(status
);
1007 static void test_fd_passing_child(int sd
)
1011 struct msghdr msghdr
;
1012 struct cmsghdr
*cmsg
;
1016 memset(buf
, '\0', BUFSIZE
);
1018 fd
= open(TEST_TXT_FILE
, O_CREAT
|O_TRUNC
|O_RDWR
);
1020 test_fail("could not open test.txt");
1023 msghdr
.msg_name
= NULL
;
1024 msghdr
.msg_namelen
= 0;
1028 msghdr
.msg_iov
= &iov
;
1029 msghdr
.msg_iovlen
= 1;
1031 msghdr
.msg_control
= buf
;
1032 msghdr
.msg_controllen
= CMSG_SPACE(sizeof(int));
1034 msghdr
.msg_flags
= 0;
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
;
1041 ((int *) CMSG_DATA(cmsg
))[0] = fd
;
1043 rc
= sendmsg(sd
, &msghdr
, 0);
1045 test_fail("could not send message");
1048 memset(buf
, '\0', BUFSIZE
);
1049 rc
= read(sd
, buf
, BUFSIZE
);
1051 test_fail("could not read from socket");
1054 if (strcmp(buf
, "done") != 0) {
1055 test_fail("we didn't read the right message");
1058 memset(buf
, '\0', BUFSIZE
);
1059 rc
= lseek(fd
, 0, SEEK_SET
);
1061 test_fail("could not seek to start of test.txt");
1064 rc
= read(fd
, buf
, BUFSIZE
);
1066 test_fail("could not read from test.txt");
1069 if (strcmp(buf
, MSG
) != 0) {
1070 test_fail("other process didn't write MSG to test.txt");
1075 test_fail("could not close test.txt");
1080 test_fail("could not close socket");
1083 rc
= unlink(TEST_TXT_FILE
);
1085 test_fail("could not unlink test.txt");
1091 static void test_fd_passing_parent(int sd
)
1095 struct msghdr msghdr
;
1096 struct cmsghdr
*cmsg
;
1100 memset(buf
, '\0', BUFSIZE
);
1102 msghdr
.msg_name
= NULL
;
1103 msghdr
.msg_namelen
= 0;
1107 msghdr
.msg_iov
= &iov
;
1108 msghdr
.msg_iovlen
= 1;
1110 msghdr
.msg_iov
= &iov
;
1111 msghdr
.msg_iovlen
= 1;
1113 msghdr
.msg_control
= buf
;
1114 msghdr
.msg_controllen
= BUFSIZE
;
1116 msghdr
.msg_flags
= 0;
1118 rc
= recvmsg(sd
, &msghdr
, 0);
1120 test_fail("could not recv message.");
1123 cmsg
= CMSG_FIRSTHDR(&msghdr
);
1124 fd
= ((int *) CMSG_DATA(cmsg
))[0];
1126 rc
= write(fd
, MSG
, strlen(MSG
));
1127 if (rc
!= strlen(MSG
)) {
1128 test_fail("could not write the full message to test.txt");
1133 test_fail("could not close test.txt");
1136 memset(buf
, '\0', BUFSIZE
);
1137 strcpy(buf
, "done");
1138 rc
= write(sd
, buf
, BUFSIZE
);
1140 test_fail("could not write to socket");
1145 test_fail("could not close socket");
1149 static void test_permissions(void) {
1150 /* Test bind and connect for permission verification
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
1158 struct sockaddr_un addr
;
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);
1164 UNLINK(TEST_SUN_PATH
);
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
));
1174 test_fail("bind() should not have worked");
1178 rc
= waitpid(pid
, &status
, 0);
1179 errct
+= WEXITSTATUS(status
);
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.
1186 debug("installing signal handler");
1187 if (signal(SIGUSR1
, test_xfer_sighdlr
) == SIG_ERR
) {
1188 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed");
1191 debug("signal handler installed");
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");
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
));
1207 test_fail("connect should not have worked");
1210 SOCKET(sd
, PF_UNIX
, SOCK_STREAM
, 0);
1211 rc
= bind(sd
, (struct sockaddr
*) &addr
,
1212 sizeof(struct sockaddr_un
));
1214 test_fail("bind() should have worked");
1219 test_fail("listen(sd, 8) should have worked");
1225 rc
= waitpid(pid
, &status
, 0);
1226 errct
+= WEXITSTATUS(status
);
1229 UNLINK(TEST_SUN_PATH
);
1232 static void test_fd_passing(void) {
1238 rc
= socketpair(AF_UNIX
, SOCK_STREAM
, 0, sv
);
1240 test_fail("socketpair failed");
1245 test_fail("fork() failed");
1249 test_fail("could not close sv[0]");
1254 test_fail("could not close sv[1]");
1258 } else if (pid
== 0) {
1261 test_fail("could not close sv[0]");
1264 test_fd_passing_child(sv
[1]);
1265 test_fail("should never get here");
1270 test_fail("could not close sv[1]");
1273 test_fd_passing_parent(sv
[0]);
1275 /* wait for client to exit */
1278 rc
= waitpid(pid
, &status
, 0);
1279 } while (rc
== -1 && errno
== EINTR
);
1281 /* we use the exit status to get its error count */
1282 errct
+= WEXITSTATUS(status
);
1286 static void test_select(void)
1290 fd_set readfds
, writefds
;
1299 tv
.tv_usec
= 0; /* 2 sec time out */
1301 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
1302 test_fail("Can't open socket pair.");
1304 FD_SET(socks
[0], &readfds
);
1305 nfds
= socks
[0] + 1;
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");
1312 res
= select(nfds
, &readfds
, NULL
, NULL
, &tv
);
1314 test_fail("select should've returned 1 ready fd\n");
1316 if (!(FD_ISSET(socks
[0], &readfds
))) {
1317 test_fail("The server didn't respond within 2 seconds");
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");
1326 /* Try again the other way around: create a socketpair, close the
1327 * read end, and try to write. This should cause an EPIPE */
1330 tv
.tv_usec
= 0; /* 2 sec time out */
1332 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
1333 test_fail("Can't open socket pair.");
1335 FD_SET(socks
[1], &writefds
);
1336 nfds
= socks
[1] + 1;
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");
1343 res
= select(nfds
, NULL
, &writefds
, NULL
, &tv
);
1345 test_fail("select should've returned 1 ready fd\n");
1347 if (!(FD_ISSET(socks
[1], &writefds
))) {
1348 test_fail("The server didn't respond within 2 seconds");
1351 /* Now try to write to closed pipe */
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");
1357 if (errno
!= EPIPE
) {
1358 printf("errno = %d\n", errno
);
1359 test_fail("writing to closed pipe should return EPIPE\n");
1365 static void test_select_close(void)
1371 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
1372 test_fail("Can't open socket pair.");
1381 test_fail("Can't fork.");
1389 FD_SET(socks
[0], &readfds
);
1391 tv
.tv_usec
= 0; /* 2 sec time out */
1393 res
= select(socks
[0] + 1, &readfds
, NULL
, NULL
, &tv
);
1395 test_fail("select should've returned 1 ready fd\n");
1397 if (!(FD_ISSET(socks
[0], &readfds
))) {
1398 test_fail("The server didn't respond within 2 seconds");
1406 static void test_fchmod(void)
1409 struct stat st1
, st2
;
1411 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, socks
) < 0) {
1412 test_fail("Can't open socket pair.");
1415 if (fstat(socks
[0], &st1
) < 0 || fstat(socks
[1], &st2
) < 0) {
1416 test_fail("fstat failed.");
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.");
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).");
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).");
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).
1449 struct sockaddr_un addr
, saddr
, saddr2
;
1454 int sd
, sd2
, csd
, fd
;
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.
1461 UNLINK(TEST_SUN_PATH
);
1463 memset(&addr
, 0, sizeof(addr
));
1464 addr
.sun_family
= AF_UNIX
;
1465 strlcpy(addr
.sun_path
, TEST_SUN_PATH
, sizeof(addr
.sun_path
));
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");
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");
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");
1488 UNLINK(TEST_SUN_PATH
);
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.
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");
1506 if ((csd
= socket(PF_UNIX
, SOCK_DGRAM
, 0)) == -1)
1507 test_fail("Can't open client socket");
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");
1516 test_fail("Transmission failure");
1518 if (unlink(TEST_SUN_PATH
) != 0)
1519 test_fail("Can't unlink socket");
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");
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");
1543 test_fail("Transmission failure");
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");
1551 if (unlink(TEST_SUN_PATH
) != 0)
1552 test_fail("Can't unlink socket");
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).
1564 if ((fd
= open(TEST_SUN_PATH
, O_WRONLY
| O_CREAT
| O_EXCL
, 0700)) < 0)
1565 test_fail("Can't create regular file");
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");
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");
1589 UNLINK(TEST_SUN_PATH
);
1592 * The created socket file should have an access mode of 0777 corrected
1593 * with the calling process's file mode creation mask.
1595 omask
= umask(045123);
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");
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");
1610 UNLINK(TEST_SUN_PATH
);
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.
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");
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");
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");
1637 UNLINK(TEST_SUN_PATH
);
1640 int main(int argc
, char *argv
[])
1643 struct sockaddr_un clientaddr
= {
1644 .sun_family
= AF_UNIX
,
1645 .sun_path
= TEST_SUN_PATH
,
1647 struct sockaddr_un clientaddr2
= {
1648 .sun_family
= AF_UNIX
,
1649 .sun_path
= TEST_SUN_PATHB
,
1651 struct sockaddr_un clientaddrsym
= {
1652 .sun_family
= AF_UNIX
,
1653 .sun_path
= TEST_SYM_A
,
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
),
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
,
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
,
1679 debug("entering main()");
1683 /* This test was written before UDS started supporting SIGPIPE. */
1684 signal(SIGPIPE
, SIG_IGN
);
1690 test_getsockname(&info
);
1692 test_shutdown(&info
);
1698 test_shutdown(&info
);
1701 test_sockopts(&info
);
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
]);
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();
1720 test_select_close();
1722 test_nonblock(&info
);
1723 test_connect_nb(&info
);
1725 test_connect_close(&info
);
1726 test_listen_close(&info
);
1727 test_listen_close_nb(&info
);
1732 return -1; /* we should never get here */