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