1*b749d6b5Santon #include <sys/socket.h>
2*b749d6b5Santon #include <sys/un.h>
3*b749d6b5Santon
4*b749d6b5Santon #include <string.h>
5*b749d6b5Santon #include <stdlib.h>
6*b749d6b5Santon #include <unistd.h>
7*b749d6b5Santon
8*b749d6b5Santon #include "unveil.h"
9*b749d6b5Santon
10*b749d6b5Santon static int
test_bind_unix_socket(int do_uv)11*b749d6b5Santon test_bind_unix_socket(int do_uv)
12*b749d6b5Santon {
13*b749d6b5Santon struct sockaddr_un sun1, sun2, sun3;
14*b749d6b5Santon char *path1, *path2, *path3;
15*b749d6b5Santon int c_fd1, c_fd2, fd1, fd2, fd3;
16*b749d6b5Santon
17*b749d6b5Santon char uv_dir3[] = "/tmp/uvdir3.XXXXXX";
18*b749d6b5Santon
19*b749d6b5Santon if (asprintf(&path1, "%s/1.sock", uv_dir1) == -1)
20*b749d6b5Santon err(1, NULL);
21*b749d6b5Santon if (asprintf(&path2, "%s/2.sock", uv_dir2) == -1)
22*b749d6b5Santon err(1, NULL);
23*b749d6b5Santon if (asprintf(&path3, "%s/3.sock", uv_dir3) == -1)
24*b749d6b5Santon err(1, NULL);
25*b749d6b5Santon
26*b749d6b5Santon memset(&sun1, 0, sizeof(sun1));
27*b749d6b5Santon sun1.sun_family = AF_UNIX;
28*b749d6b5Santon strlcpy(sun1.sun_path, path1, sizeof(sun1.sun_path));
29*b749d6b5Santon
30*b749d6b5Santon memset(&sun2, 0, sizeof(sun2));
31*b749d6b5Santon sun2.sun_family = AF_UNIX;
32*b749d6b5Santon strlcpy(sun2.sun_path, path2, sizeof(sun2.sun_path));
33*b749d6b5Santon
34*b749d6b5Santon memset(&sun3, 0, sizeof(sun3));
35*b749d6b5Santon sun3.sun_family = AF_UNIX;
36*b749d6b5Santon strlcpy(sun3.sun_path, path3, sizeof(sun3.sun_path));
37*b749d6b5Santon
38*b749d6b5Santon if (unlink(path1) == -1)
39*b749d6b5Santon if (errno != ENOENT) {
40*b749d6b5Santon warn("%s: unlink %s", __func__, path1);
41*b749d6b5Santon return -1;
42*b749d6b5Santon }
43*b749d6b5Santon if (unlink(path2) == -1)
44*b749d6b5Santon if (errno != ENOENT) {
45*b749d6b5Santon warn("%s: unlink %s", __func__, path2);
46*b749d6b5Santon return -1;
47*b749d6b5Santon }
48*b749d6b5Santon if (unlink(path3) == -1)
49*b749d6b5Santon if (errno != ENOENT) {
50*b749d6b5Santon warn("%s: unlink %s", __func__, path3);
51*b749d6b5Santon return -1;
52*b749d6b5Santon }
53*b749d6b5Santon
54*b749d6b5Santon if (do_uv) {
55*b749d6b5Santon printf("testing bind and connect on unix socket\n");
56*b749d6b5Santon /* printf("testing bind on unix socket %s and %s\n", path1, path2); */
57*b749d6b5Santon if (unveil(uv_dir1, "wc") == -1) /* both bind and connect work */
58*b749d6b5Santon err(1, "unveil");
59*b749d6b5Santon if (unveil(uv_dir2, "c") == -1) /* bind works, connect fails */
60*b749d6b5Santon err(1, "unveil");
61*b749d6b5Santon if (unveil(uv_dir3, "") == -1) /* no bind, dont test anything else */
62*b749d6b5Santon err(1, "unveil");
63*b749d6b5Santon }
64*b749d6b5Santon
65*b749d6b5Santon if ((fd1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
66*b749d6b5Santon err(1, "%s: socket", __func__);
67*b749d6b5Santon UV_SHOULD_SUCCEED(
68*b749d6b5Santon (bind(fd1, (struct sockaddr *)&sun1, sizeof(sun1)) == -1), "bind");
69*b749d6b5Santon if (listen(fd1, 5) == -1)
70*b749d6b5Santon err(1, "%s: listen", __func__);
71*b749d6b5Santon
72*b749d6b5Santon if ((fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
73*b749d6b5Santon err(1, "%s: socket", __func__);
74*b749d6b5Santon UV_SHOULD_SUCCEED(
75*b749d6b5Santon (bind(fd2, (struct sockaddr *)&sun2, sizeof(sun2)) == -1), "bind");
76*b749d6b5Santon if (listen(fd2, 5) == -1)
77*b749d6b5Santon err(1, "%s: listen", __func__);
78*b749d6b5Santon
79*b749d6b5Santon if ((fd3 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
80*b749d6b5Santon err(1, "%s: socket", __func__);
81*b749d6b5Santon UV_SHOULD_ENOENT(
82*b749d6b5Santon (bind(fd3, (struct sockaddr *)&sun3, sizeof(sun3)) == -1), "bind");
83*b749d6b5Santon
84*b749d6b5Santon /* Connect to control socket. */
85*b749d6b5Santon
86*b749d6b5Santon if ((c_fd1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
87*b749d6b5Santon err(1, "socket");
88*b749d6b5Santon UV_SHOULD_SUCCEED(
89*b749d6b5Santon (connect(c_fd1, (struct sockaddr *)&sun1, sizeof(sun1)) == -1),
90*b749d6b5Santon "connect");
91*b749d6b5Santon
92*b749d6b5Santon if ((c_fd2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
93*b749d6b5Santon err(1, "socket");
94*b749d6b5Santon UV_SHOULD_EACCES(
95*b749d6b5Santon (connect(c_fd2, (struct sockaddr *)&sun2, sizeof(sun2)) == -1),
96*b749d6b5Santon "connect");
97*b749d6b5Santon
98*b749d6b5Santon close(fd1);
99*b749d6b5Santon close(c_fd1);
100*b749d6b5Santon close(fd2);
101*b749d6b5Santon close(c_fd2);
102*b749d6b5Santon return 0;
103*b749d6b5Santon }
104*b749d6b5Santon
105*b749d6b5Santon int
main(void)106*b749d6b5Santon main(void)
107*b749d6b5Santon {
108*b749d6b5Santon int failures = 0;
109*b749d6b5Santon
110*b749d6b5Santon test_setup();
111*b749d6b5Santon
112*b749d6b5Santon failures += runcompare(test_bind_unix_socket);
113*b749d6b5Santon exit(failures);
114*b749d6b5Santon }
115