1 /* $NetBSD: t_socket.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */
5 #include <sys/socket.h>
9 #include <rump/rump_syscalls.h>
23 ATF_TC(cmsg_sendfd_bounds);
24 ATF_TC_HEAD(cmsg_sendfd_bounds, tc)
26 atf_tc_set_md_var(tc, "descr", "Checks that attempting to pass an "
27 "invalid fd returns an error");
30 ATF_TC_BODY(cmsg_sendfd_bounds, tc)
40 if (rump_sys_socketpair(AF_LOCAL, SOCK_STREAM, 0, s) == -1)
41 atf_tc_fail("rump_sys_socket");
43 cmp = malloc(CMSG_SPACE(sizeof(int)));
46 iov.iov_len = sizeof(int);
48 cmp->cmsg_level = SOL_SOCKET;
49 cmp->cmsg_type = SCM_RIGHTS;
50 cmp->cmsg_len = CMSG_LEN(sizeof(int));
56 msg.msg_control = cmp;
57 msg.msg_controllen = CMSG_SPACE(sizeof(int));
60 * ERROR HERE: trying to pass invalid fd
61 * (This value was previously directly used to index the fd
62 * array and therefore we are passing a hyperspace index)
64 *(int *)CMSG_DATA(cmp) = 0x12345678;
66 rump_sys_sendmsg(s[0], &msg, 0);
68 atf_tc_fail("descriptor passing failed: expected EBADF (9), "
69 "got %d\n(%s)", errno, strerror(errno));
74 ATF_TC_HEAD(cmsg_sendfd, tc)
76 atf_tc_set_md_var(tc, "descr", "Checks that fd passing works");
77 atf_tc_set_md_var(tc, "timeout", "10");
80 ATF_TC_BODY(cmsg_sendfd, tc)
85 struct sockaddr_un sun;
90 int rfd, fd[2], storage;
94 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
95 l1 = rump_pub_lwproc_curlwp();
97 /* create unix socket and bind it to a path */
98 memset(&sun, 0, sizeof(sun));
99 sun.sun_family = AF_LOCAL;
100 #define SOCKPATH "/com"
101 strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH));
102 s1 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0);
104 atf_tc_fail_errno("socket 1");
105 if (rump_sys_bind(s1, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1)
106 atf_tc_fail_errno("socket 1 bind");
107 if (rump_sys_listen(s1, 1) == -1)
108 atf_tc_fail_errno("socket 1 listen");
110 /* create second process for test */
111 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
112 (void)rump_pub_lwproc_curlwp();
114 /* connect to unix domain socket */
115 memset(&sun, 0, sizeof(sun));
116 sun.sun_family = AF_LOCAL;
117 strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH));
118 s2 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0);
120 atf_tc_fail_errno("socket 2");
121 if (rump_sys_connect(s2, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1)
122 atf_tc_fail_errno("socket 2 connect");
124 /* open a pipe and write stuff to it */
125 if (rump_sys_pipe(fd) == -1)
126 atf_tc_fail_errno("can't open pipe");
127 #define MAGICSTRING "duam xnaht"
128 if (rump_sys_write(fd[1], MAGICSTRING, sizeof(MAGICSTRING)) !=
130 atf_tc_fail_errno("pipe write"); /* XXX: errno */
132 cmp = malloc(CMSG_SPACE(sizeof(int)));
134 iov.iov_base = &storage;
135 iov.iov_len = sizeof(int);
137 cmp->cmsg_level = SOL_SOCKET;
138 cmp->cmsg_type = SCM_RIGHTS;
139 cmp->cmsg_len = CMSG_LEN(sizeof(int));
145 msg.msg_control = cmp;
146 msg.msg_controllen = CMSG_SPACE(sizeof(int));
147 *(int *)CMSG_DATA(cmp) = fd[0];
150 if (rump_sys_sendmsg(s2, &msg, 0) == -1)
151 atf_tc_fail_errno("sendmsg failed");
154 * We will read to the same cmsg space. Overwrite the space
155 * with an invalid fd to make sure we get an explicit error
156 * if we don't manage to read the fd.
158 *(int *)CMSG_DATA(cmp) = -1;
160 /* switch back to original proc */
161 rump_pub_lwproc_switch(l1);
163 /* accept connection and read fd */
165 sgot = rump_sys_accept(s1, (struct sockaddr *)&sun, &sl);
167 atf_tc_fail_errno("accept");
168 if (rump_sys_recvmsg(sgot, &msg, 0) == -1)
169 atf_tc_fail_errno("recvmsg failed");
170 rfd = *(int *)CMSG_DATA(cmp);
172 /* read from the fd */
173 memset(buf, 0, sizeof(buf));
174 if (rump_sys_read(rfd, buf, sizeof(buf)) == -1)
175 atf_tc_fail_errno("read rfd");
177 /* check that we got the right stuff */
178 if (strcmp(buf, MAGICSTRING) != 0)
179 atf_tc_fail("expected \"%s\", got \"%s\"", MAGICSTRING, buf);
182 ATF_TC(sock_cloexec);
183 ATF_TC_HEAD(sock_cloexec, tc)
185 atf_tc_set_md_var(tc, "descr", "SOCK_CLOEXEC kernel invariant failure");
188 ATF_TC_BODY(sock_cloexec, tc)
192 rump_pub_lwproc_rfork(RUMP_RFFDG);
193 if (rump_sys_socket(-1, SOCK_CLOEXEC, 0) != -1)
194 atf_tc_fail("invalid socket parameters unexpectedly worked");
195 rump_pub_lwproc_releaselwp();
200 ATF_TP_ADD_TC(tp, cmsg_sendfd);
201 ATF_TP_ADD_TC(tp, cmsg_sendfd_bounds);
202 ATF_TP_ADD_TC(tp, sock_cloexec);
204 return atf_no_error();