xref: /illumos-gate/usr/src/test/os-tests/tests/oclo/oclo_errors.c (revision 0250c53ad267726f2438e3c6556199a0bbf588a2)
1*0250c53aSRobert Mustacchi /*
2*0250c53aSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*0250c53aSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*0250c53aSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*0250c53aSRobert Mustacchi  * 1.0 of the CDDL.
6*0250c53aSRobert Mustacchi  *
7*0250c53aSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*0250c53aSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*0250c53aSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*0250c53aSRobert Mustacchi  */
11*0250c53aSRobert Mustacchi 
12*0250c53aSRobert Mustacchi /*
13*0250c53aSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
14*0250c53aSRobert Mustacchi  */
15*0250c53aSRobert Mustacchi 
16*0250c53aSRobert Mustacchi /*
17*0250c53aSRobert Mustacchi  * Verify that unsupported flags will properly generate errors across the
18*0250c53aSRobert Mustacchi  * functions that we know perform strict error checking. This includes:
19*0250c53aSRobert Mustacchi  *
20*0250c53aSRobert Mustacchi  *  o fcntl(..., F_DUP3FD, ...)
21*0250c53aSRobert Mustacchi  *  o dup3()
22*0250c53aSRobert Mustacchi  *  o pipe2()
23*0250c53aSRobert Mustacchi  *  o socket()
24*0250c53aSRobert Mustacchi  *  o accept4()
25*0250c53aSRobert Mustacchi  */
26*0250c53aSRobert Mustacchi 
27*0250c53aSRobert Mustacchi #include <stdlib.h>
28*0250c53aSRobert Mustacchi #include <err.h>
29*0250c53aSRobert Mustacchi #include <stdio.h>
30*0250c53aSRobert Mustacchi #include <unistd.h>
31*0250c53aSRobert Mustacchi #include <sys/stdbool.h>
32*0250c53aSRobert Mustacchi #include <errno.h>
33*0250c53aSRobert Mustacchi #include <string.h>
34*0250c53aSRobert Mustacchi #include <fcntl.h>
35*0250c53aSRobert Mustacchi #include <limits.h>
36*0250c53aSRobert Mustacchi #include <sys/socket.h>
37*0250c53aSRobert Mustacchi 
38*0250c53aSRobert Mustacchi static bool
oclo_check(const char * desc,const char * act,int ret,int e)39*0250c53aSRobert Mustacchi oclo_check(const char *desc, const char *act, int ret, int e)
40*0250c53aSRobert Mustacchi {
41*0250c53aSRobert Mustacchi 	if (ret >= 0) {
42*0250c53aSRobert Mustacchi 		warnx("TEST FAILED: %s: fd was %s!", desc, act);
43*0250c53aSRobert Mustacchi 		return (false);
44*0250c53aSRobert Mustacchi 	} else if (errno != EINVAL) {
45*0250c53aSRobert Mustacchi 		int e = errno;
46*0250c53aSRobert Mustacchi 		warnx("TEST FAILED: %s: failed with %s, expected "
47*0250c53aSRobert Mustacchi 		    "EINVAL", desc, strerrorname_np(e));
48*0250c53aSRobert Mustacchi 		return (false);
49*0250c53aSRobert Mustacchi 	}
50*0250c53aSRobert Mustacchi 
51*0250c53aSRobert Mustacchi 	(void) printf("TEST PASSED: %s: correctly failed with EINVAL\n",
52*0250c53aSRobert Mustacchi 	    desc);
53*0250c53aSRobert Mustacchi 	return (true);
54*0250c53aSRobert Mustacchi }
55*0250c53aSRobert Mustacchi 
56*0250c53aSRobert Mustacchi static bool
oclo_dup3(const char * desc,int flags)57*0250c53aSRobert Mustacchi oclo_dup3(const char *desc, int flags)
58*0250c53aSRobert Mustacchi {
59*0250c53aSRobert Mustacchi 	int fd = dup3(STDERR_FILENO, 23, flags);
60*0250c53aSRobert Mustacchi 	return (oclo_check(desc, "duplicated", fd, errno));
61*0250c53aSRobert Mustacchi }
62*0250c53aSRobert Mustacchi 
63*0250c53aSRobert Mustacchi static bool
oclo_dup3fd(const char * desc,int flags)64*0250c53aSRobert Mustacchi oclo_dup3fd(const char *desc, int flags)
65*0250c53aSRobert Mustacchi {
66*0250c53aSRobert Mustacchi 	int fd = fcntl(STDERR_FILENO, F_DUP3FD, 23, flags);
67*0250c53aSRobert Mustacchi 	return (oclo_check(desc, "duplicated", fd, errno));
68*0250c53aSRobert Mustacchi }
69*0250c53aSRobert Mustacchi 
70*0250c53aSRobert Mustacchi 
71*0250c53aSRobert Mustacchi static bool
oclo_pipe2(const char * desc,int flags)72*0250c53aSRobert Mustacchi oclo_pipe2(const char *desc, int flags)
73*0250c53aSRobert Mustacchi {
74*0250c53aSRobert Mustacchi 	int fds[2], ret;
75*0250c53aSRobert Mustacchi 
76*0250c53aSRobert Mustacchi 	ret = pipe2(fds, flags);
77*0250c53aSRobert Mustacchi 	return (oclo_check(desc, "piped", ret, errno));
78*0250c53aSRobert Mustacchi }
79*0250c53aSRobert Mustacchi 
80*0250c53aSRobert Mustacchi static bool
oclo_socket(const char * desc,int type)81*0250c53aSRobert Mustacchi oclo_socket(const char *desc, int type)
82*0250c53aSRobert Mustacchi {
83*0250c53aSRobert Mustacchi 	int fd = socket(PF_UNIX, SOCK_STREAM | type, 0);
84*0250c53aSRobert Mustacchi 	return (oclo_check(desc, "created", fd, errno));
85*0250c53aSRobert Mustacchi }
86*0250c53aSRobert Mustacchi 
87*0250c53aSRobert Mustacchi static bool
oclo_accept(const char * desc,int flags)88*0250c53aSRobert Mustacchi oclo_accept(const char *desc, int flags)
89*0250c53aSRobert Mustacchi {
90*0250c53aSRobert Mustacchi 	int sock, fd, e;
91*0250c53aSRobert Mustacchi 	struct sockaddr_in in;
92*0250c53aSRobert Mustacchi 
93*0250c53aSRobert Mustacchi 	sock = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
94*0250c53aSRobert Mustacchi 	if (sock < 0) {
95*0250c53aSRobert Mustacchi 		warn("TEST FAILED: %s: failed to create listen socket", desc);
96*0250c53aSRobert Mustacchi 		return (false);
97*0250c53aSRobert Mustacchi 	}
98*0250c53aSRobert Mustacchi 
99*0250c53aSRobert Mustacchi 	(void) memset(&in, 0, sizeof (in));
100*0250c53aSRobert Mustacchi 	in.sin_family = AF_INET;
101*0250c53aSRobert Mustacchi 	in.sin_port = 0;
102*0250c53aSRobert Mustacchi 	in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
103*0250c53aSRobert Mustacchi 
104*0250c53aSRobert Mustacchi 	if (bind(sock, (struct sockaddr *)&in, sizeof (in)) != 0) {
105*0250c53aSRobert Mustacchi 		warn("TEST FAILED: %s: failed to bind socket", desc);
106*0250c53aSRobert Mustacchi 		(void) close(sock);
107*0250c53aSRobert Mustacchi 		return (false);
108*0250c53aSRobert Mustacchi 	}
109*0250c53aSRobert Mustacchi 
110*0250c53aSRobert Mustacchi 	if (listen(sock, 5) < 0) {
111*0250c53aSRobert Mustacchi 		warn("TEST FAILED: %s: failed to listen on socket", desc);
112*0250c53aSRobert Mustacchi 		(void) close(sock);
113*0250c53aSRobert Mustacchi 		return (false);
114*0250c53aSRobert Mustacchi 	}
115*0250c53aSRobert Mustacchi 
116*0250c53aSRobert Mustacchi 
117*0250c53aSRobert Mustacchi 	fd = accept4(sock, NULL, NULL, flags);
118*0250c53aSRobert Mustacchi 	e = errno;
119*0250c53aSRobert Mustacchi 	(void) close(sock);
120*0250c53aSRobert Mustacchi 	return (oclo_check(desc, "accepted", fd, e));
121*0250c53aSRobert Mustacchi }
122*0250c53aSRobert Mustacchi 
123*0250c53aSRobert Mustacchi int
main(void)124*0250c53aSRobert Mustacchi main(void)
125*0250c53aSRobert Mustacchi {
126*0250c53aSRobert Mustacchi 	int ret = EXIT_SUCCESS;
127*0250c53aSRobert Mustacchi 
128*0250c53aSRobert Mustacchi 	closefrom(STDERR_FILENO + 1);
129*0250c53aSRobert Mustacchi 
130*0250c53aSRobert Mustacchi 	if (!oclo_dup3("dup3(): O_RDWR", O_RDWR)) {
131*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
132*0250c53aSRobert Mustacchi 	}
133*0250c53aSRobert Mustacchi 
134*0250c53aSRobert Mustacchi 	if (!oclo_dup3("dup3(): O_NONBLOCK|O_CLOXEC", O_NONBLOCK | O_CLOEXEC)) {
135*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
136*0250c53aSRobert Mustacchi 	}
137*0250c53aSRobert Mustacchi 
138*0250c53aSRobert Mustacchi 	if (!oclo_dup3("dup3(): O_CLOFORK|O_WRONLY", O_CLOFORK | O_WRONLY)) {
139*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
140*0250c53aSRobert Mustacchi 	}
141*0250c53aSRobert Mustacchi 
142*0250c53aSRobert Mustacchi 	if (!oclo_dup3fd("fcntl(FDUP3FD): 0x7777", 0x7777)) {
143*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
144*0250c53aSRobert Mustacchi 	}
145*0250c53aSRobert Mustacchi 
146*0250c53aSRobert Mustacchi 	if (!oclo_dup3fd("fcntl(FDUP3FD): FD_CLOEXEC|FD_CLOFORK + 1",
147*0250c53aSRobert Mustacchi 	    (FD_CLOEXEC | FD_CLOFORK) + 1)) {
148*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
149*0250c53aSRobert Mustacchi 	}
150*0250c53aSRobert Mustacchi 
151*0250c53aSRobert Mustacchi 	if (!oclo_dup3fd("fcntl(FDUP3FD): INT_MAX", INT_MAX)) {
152*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
153*0250c53aSRobert Mustacchi 	}
154*0250c53aSRobert Mustacchi 
155*0250c53aSRobert Mustacchi 
156*0250c53aSRobert Mustacchi 	if (!oclo_pipe2("pipe2(): O_RDWR", O_RDWR)) {
157*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
158*0250c53aSRobert Mustacchi 	}
159*0250c53aSRobert Mustacchi 
160*0250c53aSRobert Mustacchi 	if (!oclo_pipe2("pipe2(): O_SYNC|O_CLOXEC", O_SYNC | O_CLOEXEC)) {
161*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
162*0250c53aSRobert Mustacchi 	}
163*0250c53aSRobert Mustacchi 
164*0250c53aSRobert Mustacchi 	if (!oclo_pipe2("pipe2(): O_CLOFORK|O_WRONLY", O_CLOFORK | O_WRONLY)) {
165*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
166*0250c53aSRobert Mustacchi 	}
167*0250c53aSRobert Mustacchi 
168*0250c53aSRobert Mustacchi 	if (!oclo_pipe2("pipe2(): INT32_MAX", INT32_MAX)) {
169*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
170*0250c53aSRobert Mustacchi 	}
171*0250c53aSRobert Mustacchi 
172*0250c53aSRobert Mustacchi 	if (!oclo_socket("socket(): INT32_MAX", INT32_MAX)) {
173*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
174*0250c53aSRobert Mustacchi 	}
175*0250c53aSRobert Mustacchi 
176*0250c53aSRobert Mustacchi 	if (!oclo_socket("socket(): 3 << 25", 3 << 25)) {
177*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
178*0250c53aSRobert Mustacchi 	}
179*0250c53aSRobert Mustacchi 
180*0250c53aSRobert Mustacchi 	if (!oclo_accept("accept4(): INT32_MAX", INT32_MAX)) {
181*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
182*0250c53aSRobert Mustacchi 	}
183*0250c53aSRobert Mustacchi 
184*0250c53aSRobert Mustacchi 	if (!oclo_accept("accept4(): 3 << 25", 3 << 25)) {
185*0250c53aSRobert Mustacchi 		ret = EXIT_FAILURE;
186*0250c53aSRobert Mustacchi 	}
187*0250c53aSRobert Mustacchi 
188*0250c53aSRobert Mustacchi 	if (ret == EXIT_SUCCESS) {
189*0250c53aSRobert Mustacchi 		(void) printf("All tests completed successfully\n");
190*0250c53aSRobert Mustacchi 	}
191*0250c53aSRobert Mustacchi 
192*0250c53aSRobert Mustacchi 	return (ret);
193*0250c53aSRobert Mustacchi }
194