1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
33 #include <osTest.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/uio.h>
37 #include <fcntl.h>
38 #include <signal.h>
39
40 static struct iovec gIov[IOV_MAX + 1];
41
SocketNullTestInternal(int sfd)42 static int SocketNullTestInternal(int sfd)
43 {
44 int ret;
45 struct sockaddr addr = {0};
46 struct sockaddr *bad = reinterpret_cast<struct sockaddr *>(0xbad);
47 socklen_t addrlen = sizeof(addr);
48 socklen_t zero = 0;
49 struct msghdr message = {0};
50 void *badUserAddr = reinterpret_cast<void *>(0x3effffff);
51
52 /**
53 * accept
54 */
55 ret = accept(sfd, NULL, NULL);
56 LogPrintln("accept: %d, errno=%d", ret, errno);
57 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
58
59 ret = accept(sfd, NULL, &addrlen);
60 LogPrintln("accept: %d, errno=%d", ret, errno);
61 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
62
63 ret = accept(sfd, bad, &zero);
64 LogPrintln("accept: %d, errno=%d", ret, errno);
65 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
66
67 ret = accept(sfd, &addr, NULL);
68 LogPrintln("accept: %d, errno=%d", ret, errno);
69 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
70
71 /**
72 * bind
73 */
74 ret = bind(sfd, NULL, addrlen);
75 LogPrintln("bind: %d, errno=%d", ret, errno);
76 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
77
78 ret = bind(sfd, bad, 0);
79 LogPrintln("bind: %d, errno=%d", ret, errno);
80 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
81
82 /**
83 * getpeername
84 */
85 ret = getpeername(sfd, NULL, NULL);
86 LogPrintln("getpeername: %d, errno=%d", ret, errno);
87 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
88
89 ret = getpeername(sfd, NULL, &addrlen);
90 LogPrintln("getpeername: %d, errno=%d", ret, errno);
91 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
92
93 ret = getpeername(sfd, &addr, NULL);
94 LogPrintln("getpeername: %d, errno=%d", ret, errno);
95 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
96
97 zero = 0;
98 ret = getpeername(sfd, bad, &zero);
99 LogPrintln("getpeername: %d, errno=%d", ret, errno);
100 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
101 ICUNIT_ASSERT_EQUAL(errno, ENOTCONN, errno);
102
103 /**
104 * getsockname
105 */
106 ret = getsockname(sfd, NULL, NULL);
107 LogPrintln("getsockname: %d, errno=%d", ret, errno);
108 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
109
110 ret = getsockname(sfd, NULL, &addrlen);
111 LogPrintln("getsockname: %d, errno=%d", ret, errno);
112 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
113
114 ret = getsockname(sfd, &addr, NULL);
115 LogPrintln("getsockname: %d, errno=%d", ret, errno);
116 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
117
118 zero = 0;
119 ret = getsockname(sfd, bad, &zero);
120 LogPrintln("getsockname: %d, errno=%d", ret, errno);
121 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
122
123 /**
124 * getsockopt
125 */
126 ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, NULL);
127 LogPrintln("getsockopt: %d, errno=%d", ret, errno);
128 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
129
130 ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, &addrlen);
131 LogPrintln("getsockopt: %d, errno=%d", ret, errno);
132 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
133
134 ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &addr, NULL);
135 LogPrintln("getsockopt: %d, errno=%d", ret, errno);
136 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
137
138 zero = 0;
139 ret = getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, &zero);
140 LogPrintln("getsockopt: %d, errno=%d", ret, errno);
141 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
142
143 /**
144 * setsockopt
145 */
146 ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, NULL, addrlen);
147 LogPrintln("setsockopt: %d, errno=%d", ret, errno);
148 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
149
150 ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, 0);
151 LogPrintln("setsockopt: %d, errno=%d", ret, errno);
152 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
153
154 ret = setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, bad, addrlen);
155 LogPrintln("setsockopt: %d, errno=%d", ret, errno);
156 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
157
158 /**
159 * connect
160 */
161 ret = connect(sfd, NULL, addrlen);
162 LogPrintln("connect: %d, errno=%d", ret, errno);
163 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
164
165 ret = connect(sfd, bad, 0);
166 LogPrintln("connect: %d, errno=%d", ret, errno);
167 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
168
169 ret = connect(sfd, bad, addrlen);
170 LogPrintln("connect: %d, errno=%d", ret, errno);
171 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
172
173 /**
174 * recv
175 */
176 ret = recv(sfd, NULL, 1, MSG_DONTWAIT);
177 LogPrintln("recv: %d, errno=%d", ret, errno);
178 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
179
180 /**
181 * recvfrom
182 */
183 ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, NULL);
184 LogPrintln("recvfrom: %d, errno=%d", ret, errno);
185 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
186
187 ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, NULL, &addrlen);
188 LogPrintln("recvfrom: %d, errno=%d", ret, errno);
189 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
190
191 ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, &addr, NULL);
192 LogPrintln("recvfrom: %d, errno=%d", ret, errno);
193 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
194
195 zero = 0;
196 ret = recvfrom(sfd, NULL, 1, MSG_DONTWAIT, bad, &zero);
197 LogPrintln("recvfrom: %d, errno=%d", ret, errno);
198 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
199
200 /**
201 * recvmsg
202 */
203 ret = recvmsg(sfd, NULL, MSG_DONTWAIT);
204 LogPrintln("recvmsg: %d, errno=%d", ret, errno);
205 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
206
207 message.msg_iov = NULL;
208 message.msg_iovlen = 1;
209 ret = recvmsg(sfd, &message, MSG_DONTWAIT);
210 LogPrintln("recvmsg: %d, errno=%d", ret, errno);
211 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
212
213 message.msg_iov = gIov;
214 message.msg_iovlen = 1 + IOV_MAX;
215 ret = recvmsg(sfd, &message, MSG_DONTWAIT);
216 LogPrintln("recvmsg: %d, errno=%d", ret, errno);
217 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
218
219 message.msg_iov = reinterpret_cast<struct iovec *>(0xbad);
220 message.msg_iovlen = 1;
221 ret = recvmsg(sfd, &message, MSG_DONTWAIT);
222 LogPrintln("recvmsg: %d, errno=%d", ret, errno);
223 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
224
225 message.msg_iov = reinterpret_cast<struct iovec *>(0xbad);
226 message.msg_iovlen = 0;
227 ret = recvmsg(sfd, &message, MSG_DONTWAIT);
228 LogPrintln("recvmsg: %d, errno=%d", ret, errno);
229 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
230
231 /**
232 * send
233 */
234 ret = send(sfd, NULL, 1, MSG_NOSIGNAL);
235 LogPrintln("send: %d, errno=%d", ret, errno);
236 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
237
238 ret = send(sfd, bad, 0, MSG_NOSIGNAL);
239 LogPrintln("send: %d, errno=%d", ret, errno);
240 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
241
242 /**
243 * sendmsg
244 */
245 ret = sendmsg(sfd, NULL, MSG_NOSIGNAL);
246 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
247 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
248
249 message.msg_iov = NULL;
250 message.msg_iovlen = 1;
251 ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
252 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
253 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
254
255 message.msg_iov = gIov;
256 message.msg_iovlen = IOV_MAX + 1;
257 ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
258 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
259 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
260
261 message.msg_iov = gIov;
262 message.msg_iovlen = (~0UL / sizeof(struct iovec)) + 2; // Test overflow
263 ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
264 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
265 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
266
267 message.msg_iov = reinterpret_cast<struct iovec *>(0xbad);
268 message.msg_iovlen = 1;
269 ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
270 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
271 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
272
273 message.msg_iov = reinterpret_cast<struct iovec *>(0xbad);
274 message.msg_iovlen = 0;
275 ret = sendmsg(sfd, &message, MSG_NOSIGNAL);
276 LogPrintln("sendmsg: %d, errno=%d", ret, errno);
277 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
278
279 /**
280 * sendto
281 */
282 ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, NULL, addrlen);
283 LogPrintln("sendto: %d, errno=%d", ret, errno);
284 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
285
286 ret = sendto(sfd, NULL, 1, MSG_NOSIGNAL, &addr, addrlen);
287 LogPrintln("sendto: %d, errno=%d", ret, errno);
288 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
289
290 ret = sendto(sfd, bad, 0, MSG_NOSIGNAL, &addr, addrlen);
291 LogPrintln("sendto: %d, errno=%d", ret, errno);
292 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
293
294 ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, NULL, addrlen);
295 LogPrintln("sendto: %d, errno=%d", ret, errno);
296 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
297
298 ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, 0);
299 LogPrintln("sendto: %d, errno=%d", ret, errno);
300 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
301
302 ret = sendto(sfd, "NULL", 4, MSG_NOSIGNAL, bad, addrlen);
303 LogPrintln("sendto: %d, errno=%d", ret, errno);
304 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
305
306 /**
307 * read/readv
308 */
309 ret = read(sfd, NULL, 1);
310 LogPrintln("read: %d, errno=%d", ret, errno);
311 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
312
313 ret = read(sfd, NULL, 0);
314 LogPrintln("read: %d, errno=%d", ret, errno);
315 ICUNIT_ASSERT_EQUAL(ret, 0, errno);
316
317 ret = read(sfd, bad, 1);
318 LogPrintln("read: %d, errno=%d", ret, errno);
319 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
320
321 ret = read(sfd, badUserAddr, 1);
322 LogPrintln("read: %d, errno=%d", ret, errno);
323 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
324
325 ret = read(sfd, bad, 0);
326 LogPrintln("read: %d, errno=%d", ret, errno);
327 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
328
329 ret = readv(sfd, reinterpret_cast<struct iovec *>(bad), 0);
330 LogPrintln("readv: %d, errno=%d", ret, errno);
331 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
332
333 ret = readv(sfd, reinterpret_cast<struct iovec *>(bad), 1);
334 LogPrintln("readv: %d, errno=%d", ret, errno);
335 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
336
337 ret = readv(sfd, gIov, 0);
338 LogPrintln("readv: %d, errno=%d", ret, errno);
339 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
340
341 ret = readv(sfd, gIov, IOV_MAX + 1);
342 LogPrintln("readv: %d, errno=%d", ret, errno);
343 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
344
345 gIov[0].iov_base = bad;
346 gIov[0].iov_len = 1;
347 ret = readv(sfd, gIov, 1);
348 LogPrintln("readv: %d, errno=%d", ret, errno);
349 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
350
351 gIov[0].iov_base = bad;
352 gIov[0].iov_len = 0;
353 ret = readv(sfd, gIov, 1);
354 LogPrintln("readv: %d, errno=%d", ret, errno);
355 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
356
357 /**
358 * write/writev
359 */
360 ret = write(sfd, NULL, 1);
361 LogPrintln("write: %d, errno=%d", ret, errno);
362 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
363
364 ret = write(sfd, NULL, 0);
365 LogPrintln("write: %d, errno=%d", ret, errno);
366 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
367
368 ret = write(sfd, bad, 1);
369 LogPrintln("write: %d, errno=%d", ret, errno);
370 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
371
372 ret = write(sfd, badUserAddr, 1);
373 LogPrintln("write: %d, errno=%d", ret, errno);
374 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
375
376 ret = write(sfd, bad, 0);
377 LogPrintln("write: %d, errno=%d", ret, errno);
378 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
379
380 ret = writev(sfd, reinterpret_cast<struct iovec *>(bad), 0);
381 LogPrintln("writev: %d, errno=%d", ret, errno);
382 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
383
384 ret = writev(sfd, reinterpret_cast<struct iovec *>(bad), 1);
385 LogPrintln("writev: %d, errno=%d", ret, errno);
386 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
387
388 ret = writev(sfd, gIov, 0);
389 LogPrintln("writev: %d, errno=%d", ret, errno);
390 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
391
392 ret = writev(sfd, gIov, IOV_MAX + 1);
393 LogPrintln("writev: %d, errno=%d", ret, errno);
394 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
395
396 gIov[0].iov_base = bad;
397 gIov[0].iov_len = 1;
398 ret = writev(sfd, gIov, 1);
399 LogPrintln("writev: %d, errno=%d", ret, errno);
400 ICUNIT_ASSERT_EQUAL(ret, -1, errno);
401
402 gIov[0].iov_base = bad;
403 gIov[0].iov_len = 0;
404 ret = writev(sfd, gIov, 1);
405 LogPrintln("writev: %d, errno=%d", ret, errno);
406 ICUNIT_ASSERT_EQUAL((ret == 0 || ret == -1), 1, errno);
407
408 return ICUNIT_SUCCESS;
409 }
410
SocketSetNonBlock(int sfd)411 static int SocketSetNonBlock(int sfd)
412 {
413 int ret = fcntl(sfd, F_GETFL, 0);
414 ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
415
416 ret = fcntl(sfd, F_SETFL, ret | O_NONBLOCK);
417 ICUNIT_ASSERT_EQUAL(ret < 0, 0, errno);
418
419 return ICUNIT_SUCCESS;
420 }
421
SocketNullTest(void)422 static int SocketNullTest(void)
423 {
424 int sfd;
425
426 sighandler_t oldHdl = signal(SIGPIPE, SIG_IGN);
427
428 sfd = socket(PF_INET, SOCK_DGRAM, 0);
429 ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno);
430 LogPrintln("UDP socket: %d", sfd);
431 (void)SocketSetNonBlock(sfd);
432 (void)SocketNullTestInternal(sfd);
433 (void)close(sfd);
434
435 sfd = socket(PF_INET, SOCK_STREAM, 0);
436 ICUNIT_ASSERT_NOT_EQUAL(sfd, -1, errno);
437 LogPrintln("TCP socket: %d", sfd);
438 (void)SocketSetNonBlock(sfd);
439 (void)SocketNullTestInternal(sfd);
440 (void)close(sfd);
441
442 (void)signal(SIGPIPE, oldHdl);
443
444 return ICUNIT_SUCCESS;
445 }
446
NetSocketTest012(void)447 void NetSocketTest012(void)
448 {
449 TEST_ADD_CASE(__FUNCTION__, SocketNullTest, TEST_POSIX, TEST_TCP, TEST_LEVEL0, TEST_FUNCTION);
450 }
451
452