xref: /freebsd/tests/sys/kern/unix_stream.c (revision c27f7d6b9cf6d4ab01cb3d0972726c14e0aca146)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2018 Alan Somers
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 #include <sys/socket.h>
30 #include <sys/event.h>
31 #include <sys/select.h>
32 #include <sys/sysctl.h>
33 #include <sys/un.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <poll.h>
39 #include <pthread.h>
40 #include <pthread_np.h>
41 
42 #include <atf-c.h>
43 
44 static void
45 do_socketpair(int *sv)
46 {
47 	int s;
48 
49 	s = socketpair(PF_LOCAL, SOCK_STREAM, 0, sv);
50 	ATF_REQUIRE_EQ(0, s);
51 	ATF_REQUIRE(sv[0] >= 0);
52 	ATF_REQUIRE(sv[1] >= 0);
53 	ATF_REQUIRE(sv[0] != sv[1]);
54 }
55 
56 static u_long
57 getsendspace(void)
58 {
59 	u_long sendspace;
60 
61 	ATF_REQUIRE_MSG(sysctlbyname("net.local.stream.sendspace", &sendspace,
62 	    &(size_t){sizeof(u_long)}, NULL, 0) != -1,
63 	    "sysctl net.local.stream.sendspace failed: %s", strerror(errno));
64 
65 	return (sendspace);
66 }
67 
68 /* getpeereid(3) should work with stream sockets created via socketpair(2) */
69 ATF_TC_WITHOUT_HEAD(getpeereid);
70 ATF_TC_BODY(getpeereid, tc)
71 {
72 	int sv[2];
73 	uid_t real_euid, euid;
74 	gid_t real_egid, egid;
75 
76 	real_euid = geteuid();
77 	real_egid = getegid();
78 
79 	do_socketpair(sv);
80 
81 	ATF_REQUIRE_EQ(0, getpeereid(sv[0], &euid, &egid));
82 	ATF_CHECK_EQ(real_euid, euid);
83 	ATF_CHECK_EQ(real_egid, egid);
84 
85 	ATF_REQUIRE_EQ(0, getpeereid(sv[1], &euid, &egid));
86 	ATF_CHECK_EQ(real_euid, euid);
87 	ATF_CHECK_EQ(real_egid, egid);
88 
89 	close(sv[0]);
90 	close(sv[1]);
91 }
92 
93 /* Sending zero bytes should succeed (once regressed in aba79b0f4a3f). */
94 ATF_TC_WITHOUT_HEAD(send_0);
95 ATF_TC_BODY(send_0, tc)
96 {
97 	int sv[2];
98 
99 	do_socketpair(sv);
100 	ATF_REQUIRE(send(sv[0], sv, 0, 0) == 0);
101 	close(sv[0]);
102 	close(sv[1]);
103 }
104 
105 static void
106 check_readable_select(int fd, int expect, bool timeout)
107 {
108 	fd_set rdfds;
109 	int nfds;
110 
111 	FD_ZERO(&rdfds);
112 	FD_SET(fd, &rdfds);
113 	nfds = select(fd + 1, &rdfds, NULL, NULL, timeout ?
114 	    &(struct timeval){.tv_usec = 1000} : NULL);
115 	ATF_REQUIRE_MSG(nfds == expect,
116 	    "select() returns %d errno %d", nfds, errno);
117 }
118 
119 static void
120 check_writable_select(int fd, int expect, bool timeout)
121 {
122 	fd_set wrfds;
123 	int nfds;
124 
125 	FD_ZERO(&wrfds);
126 	FD_SET(fd, &wrfds);
127 	nfds = select(fd + 1, NULL, &wrfds, NULL, timeout ?
128 	    &(struct timeval){.tv_usec = 1000} : NULL);
129 	ATF_REQUIRE_MSG(nfds == expect,
130 	    "select() returns %d errno %d", nfds, errno);
131 }
132 
133 static void
134 check_readable_poll(int fd, int expect, bool timeout)
135 {
136 	struct pollfd pfd[1];
137 	int nfds;
138 
139 	pfd[0] = (struct pollfd){
140 		.fd = fd,
141 		.events = POLLIN | POLLRDNORM,
142 	};
143 	nfds = poll(pfd, 1, timeout ? 1 : INFTIM);
144 	ATF_REQUIRE_MSG(nfds == expect,
145 	    "poll() returns %d errno %d", nfds, errno);
146 }
147 
148 static void
149 check_writable_poll(int fd, int expect, bool timeout)
150 {
151 	struct pollfd pfd[1];
152 	int nfds;
153 
154 	pfd[0] = (struct pollfd){
155 		.fd = fd,
156 		.events = POLLOUT | POLLWRNORM,
157 	};
158 	nfds = poll(pfd, 1, timeout ? 1 : INFTIM);
159 	ATF_REQUIRE_MSG(nfds == expect,
160 	    "poll() returns %d errno %d", nfds, errno);
161 }
162 
163 static void
164 check_writable_kevent(int fd, int expect, bool timeout)
165 {
166 	struct kevent kev;
167 	int nfds, kq;
168 
169 	ATF_REQUIRE(kq = kqueue());
170 	EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
171 	nfds = kevent(kq, &kev, 1, NULL, 0, NULL);
172 	ATF_REQUIRE_MSG(nfds == 0,
173 	    "kevent() returns %d errno %d", nfds, errno);
174 	nfds = kevent(kq, NULL, 0, &kev, 1, timeout ?
175 	    &(struct timespec){.tv_nsec = 1000000} : NULL);
176 	ATF_REQUIRE_MSG(nfds == expect,
177 	    "kevent() returns %d errno %d", nfds, errno);
178 	close(kq);
179 }
180 
181 typedef void check_writable_func_t(int, int, bool);
182 struct check_writable_ctx {
183 	check_writable_func_t	*method;
184 	int			fd;
185 };
186 
187 static void *
188 check_writable_blocking_thread(void *arg)
189 {
190 	struct check_writable_ctx *ctx = arg;
191 
192 	ctx->method(ctx->fd, 1, false);
193 
194 	return (NULL);
195 }
196 
197 static void
198 full_socketpair(int *sv)
199 {
200 	void *buf;
201 	u_long sendspace;
202 
203 	sendspace = getsendspace();
204 	ATF_REQUIRE((buf = malloc(sendspace)) != NULL);
205 	do_socketpair(sv);
206 	ATF_REQUIRE(fcntl(sv[0], F_SETFL, O_NONBLOCK) != -1);
207 	do {} while (send(sv[0], buf, sendspace, 0) == (ssize_t)sendspace);
208 	ATF_REQUIRE(errno == EAGAIN);
209 	ATF_REQUIRE(fcntl(sv[0], F_SETFL, 0) != -1);
210 	free(buf);
211 }
212 
213 static void
214 full_writability_check(int *sv, check_writable_func_t method)
215 {
216 	struct check_writable_ctx ctx = {
217 		.method = method,
218 		.fd = sv[0],
219 	};
220 	pthread_t thr;
221 	void *buf;
222 	u_long space;
223 
224 	space = getsendspace() / 2;
225 	ATF_REQUIRE((buf = malloc(space)) != NULL);
226 
227 	/* First check with timeout, expecting 0 fds returned. */
228 	method(sv[0], 0, true);
229 
230 	/* Launch blocking thread. */
231 	ATF_REQUIRE(pthread_create(&thr, NULL, check_writable_blocking_thread,
232 	    &ctx) == 0);
233 
234 	/* Sleep a bit to make sure that thread is put to sleep. */
235 	usleep(10000);
236 	ATF_REQUIRE(pthread_peekjoin_np(thr, NULL) == EBUSY);
237 
238 	/* Read some data and re-check, the fd is expected to be returned. */
239 	ATF_REQUIRE(read(sv[1], buf, space) == (ssize_t)space);
240 
241 	method(sv[0], 1, true);
242 
243 	/* Now check that thread was successfully woken up and exited. */
244 	ATF_REQUIRE(pthread_join(thr, NULL) == 0);
245 
246 	close(sv[0]);
247 	close(sv[1]);
248 	free(buf);
249 }
250 
251 /*
252  * Make sure that a full socket is not reported as writable by event APIs.
253  */
254 ATF_TC_WITHOUT_HEAD(full_writability_select);
255 ATF_TC_BODY(full_writability_select, tc)
256 {
257 	int sv[2];
258 
259 	full_socketpair(sv);
260 	full_writability_check(sv, check_writable_select);
261 	close(sv[0]);
262 	close(sv[1]);
263 }
264 
265 ATF_TC_WITHOUT_HEAD(full_writability_poll);
266 ATF_TC_BODY(full_writability_poll, tc)
267 {
268 	int sv[2];
269 
270 	full_socketpair(sv);
271 	full_writability_check(sv, check_writable_poll);
272 	close(sv[0]);
273 	close(sv[1]);
274 }
275 
276 ATF_TC_WITHOUT_HEAD(full_writability_kevent);
277 ATF_TC_BODY(full_writability_kevent, tc)
278 {
279 	int sv[2];
280 
281 	full_socketpair(sv);
282 	full_writability_check(sv, check_writable_kevent);
283 	close(sv[0]);
284 	close(sv[1]);
285 }
286 
287 ATF_TC_WITHOUT_HEAD(connected_writability);
288 ATF_TC_BODY(connected_writability, tc)
289 {
290 	int sv[2];
291 
292 	do_socketpair(sv);
293 	check_writable_select(sv[0], 1, true);
294 	check_writable_poll(sv[0], 1, true);
295 	check_writable_kevent(sv[0], 1, true);
296 	close(sv[0]);
297 	close(sv[1]);
298 }
299 
300 ATF_TC_WITHOUT_HEAD(unconnected_writability);
301 ATF_TC_BODY(unconnected_writability, tc)
302 {
303 	int s;
304 
305 	ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_STREAM, 0)) > 0);
306 	check_writable_select(s, 0, true);
307 	check_writable_poll(s, 0, true);
308 	check_writable_kevent(s, 0, true);
309 	close(s);
310 }
311 
312 ATF_TC_WITHOUT_HEAD(peerclosed_writability);
313 ATF_TC_BODY(peerclosed_writability, tc)
314 {
315 	struct kevent kev;
316 	int sv[2], kq;
317 
318 	do_socketpair(sv);
319 	close(sv[1]);
320 
321 	check_writable_select(sv[0], 1, false);
322 	check_writable_poll(sv[0], 1, false);
323 
324 	ATF_REQUIRE(kq = kqueue());
325 	EV_SET(&kev, sv[0], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
326 	ATF_REQUIRE(kevent(kq, &kev, 1, &kev, 1, NULL) == 1);
327 	ATF_REQUIRE(kev.ident == (uintptr_t)sv[0] &&
328 	    kev.filter == EVFILT_WRITE &&
329 	    kev.flags == EV_EOF);
330 
331 	close(sv[0]);
332 }
333 
334 ATF_TC_WITHOUT_HEAD(peershutdown_writability);
335 ATF_TC_BODY(peershutdown_writability, tc)
336 {
337 	int sv[2];
338 
339 	do_socketpair(sv);
340 	shutdown(sv[1], SHUT_RD);
341 
342 	check_writable_select(sv[0], 1, false);
343 	check_writable_poll(sv[0], 1, false);
344 	/*
345 	 * XXXGL: historically unix(4) sockets were not reporting peer's
346 	 * shutdown(SHUT_RD) as our EV_EOF.  The kevent(2) manual page says
347 	 * "filter will set EV_EOF when the reader disconnects", which is hard
348 	 * to interpret unambigously.  For now leave the historic behavior,
349 	 * but we may want to change that in uipc_usrreq.c:uipc_filt_sowrite(),
350 	 * and then this test will look like the peerclosed_writability test.
351 	 */
352 	check_writable_kevent(sv[0], 1, false);
353 
354 	close(sv[0]);
355 	close(sv[1]);
356 }
357 
358 ATF_TC_WITHOUT_HEAD(peershutdown_readability);
359 ATF_TC_BODY(peershutdown_readability, tc)
360 {
361 	ssize_t readsz;
362 	int sv[2];
363 	char c;
364 
365 	do_socketpair(sv);
366 	shutdown(sv[1], SHUT_WR);
367 
368 	/*
369 	 * The other side should flag as readable in select(2) to allow it to
370 	 * read(2) and observe EOF.  Ensure that both poll(2) and select(2)
371 	 * are consistent here.
372 	 */
373 	check_readable_select(sv[0], 1, false);
374 	check_readable_poll(sv[0], 1, false);
375 
376 	readsz = read(sv[0], &c, sizeof(c));
377 	ATF_REQUIRE_INTEQ(0, readsz);
378 
379 	close(sv[0]);
380 	close(sv[1]);
381 }
382 
383 ATF_TP_ADD_TCS(tp)
384 {
385 	ATF_TP_ADD_TC(tp, getpeereid);
386 	ATF_TP_ADD_TC(tp, send_0);
387 	ATF_TP_ADD_TC(tp, connected_writability);
388 	ATF_TP_ADD_TC(tp, unconnected_writability);
389 	ATF_TP_ADD_TC(tp, full_writability_select);
390 	ATF_TP_ADD_TC(tp, full_writability_poll);
391 	ATF_TP_ADD_TC(tp, full_writability_kevent);
392 	ATF_TP_ADD_TC(tp, peerclosed_writability);
393 	ATF_TP_ADD_TC(tp, peershutdown_writability);
394 	ATF_TP_ADD_TC(tp, peershutdown_readability);
395 
396 	return atf_no_error();
397 }
398