1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <fcntl.h>
17 #include <limits.h>
18 #include <unistd.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <sys/wait.h>
22 #include <sigchain.h>
23 #include "fortify_test.h"
24 #include "test.h"
25
26 /**
27 * @tc.name : getcwd
28 * @tc.desc : Exception scenarios for getcwd
29 * @tc.level : Level 2
30 */
unistd_dynamic_chk_001(void)31 static void unistd_dynamic_chk_001(void)
32 {
33 struct sigaction sigabrt = {
34 .sa_handler = SignalHandler,
35 };
36
37 sigaction(SIGABRT, &sigabrt, NULL);
38 const int bufferSize = 1;
39 char buf[bufferSize];
40 size_t n = atoi("2");
41 int status;
42 int pid = fork();
43 switch (pid) {
44 case -1:
45 t_error("fork failed: %d\n", __LINE__);
46 break;
47 case 0:
48 getcwd(buf, n);
49 exit(0);
50 default:
51 waitpid(pid, &status, WUNTRACED);
52 TEST(WIFEXITED(status) == 0);
53 TEST(WIFSTOPPED(status) == 1);
54 TEST(WSTOPSIG(status) == SIGSTOP);
55 kill(pid, SIGCONT);
56 break;
57 }
58 return;
59 }
60
61 /**
62 * @tc.name : pread
63 * @tc.desc : Exception scenarios for pread
64 * @tc.level : Level 2
65 */
unistd_dynamic_chk_002(void)66 static void unistd_dynamic_chk_002(void)
67 {
68 struct sigaction sigabrt = {
69 .sa_handler = SignalHandler,
70 };
71 sigaction(SIGABRT, &sigabrt, NULL);
72
73 const int err = -1;
74 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
75 TEST(fd != err);
76
77 int status;
78 const int bufferSize = 2;
79 char buf[bufferSize];
80 size_t n = atoi("4");
81 int pid = fork();
82 switch (pid) {
83 case -1:
84 t_error("fork failed: %d\n", __LINE__);
85 break;
86 case 0:
87 pread(fd, buf, n, 0);
88 exit(0);
89 default:
90 waitpid(pid, &status, WUNTRACED);
91 TEST(WIFEXITED(status) == 0);
92 TEST(WIFSTOPPED(status) == 1);
93 TEST(WSTOPSIG(status) == SIGSTOP);
94 kill(pid, SIGCONT);
95 break;
96 }
97 close(fd);
98 return;
99 }
100
101 /**
102 * @tc.name : pread
103 * @tc.desc : Exception scenarios for pread
104 * @tc.level : Level 2
105 */
unistd_dynamic_chk_003(void)106 static void unistd_dynamic_chk_003(void)
107 {
108 struct sigaction sigabrt = {
109 .sa_handler = SignalHandler,
110 };
111 sigaction(SIGABRT, &sigabrt, NULL);
112
113 const int err = -1;
114 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
115 TEST(fd != err);
116
117 int status;
118 const int bufferSize = 2;
119 char buf[bufferSize];
120 size_t n = atoi("4") + SSIZE_MAX;
121 int pid = fork();
122 switch (pid) {
123 case -1:
124 t_error("fork failed: %d\n", __LINE__);
125 break;
126 case 0:
127 pread(fd, buf, n, 0);
128 exit(0);
129 default:
130 waitpid(pid, &status, WUNTRACED);
131 TEST(WIFEXITED(status) == 0);
132 TEST(WIFSTOPPED(status) == 1);
133 TEST(WSTOPSIG(status) == SIGSTOP);
134 kill(pid, SIGCONT);
135 break;
136 }
137 close(fd);
138 return;
139 }
140
141
142 /**
143 * @tc.name : pread64
144 * @tc.desc : Exception scenarios for pread64
145 * @tc.level : Level 2
146 */
unistd_dynamic_chk_004(void)147 static void unistd_dynamic_chk_004(void)
148 {
149 struct sigaction sigabrt = {
150 .sa_handler = SignalHandler,
151 };
152 sigaction(SIGABRT, &sigabrt, NULL);
153
154 const int err = -1;
155 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
156 TEST(fd != err);
157 int status;
158
159 const int bufferSize = 2;
160 char buf[bufferSize];
161 size_t n = atoi("4") + SSIZE_MAX;;
162 int pid = fork();
163 switch (pid) {
164 case -1:
165 t_error("fork failed: %d\n", __LINE__);
166 break;
167 case 0:
168 pread64(fd, buf, n, 0);
169 exit(0);
170 default:
171 waitpid(pid, &status, WUNTRACED);
172 TEST(WIFEXITED(status) == 0);
173 TEST(WIFSTOPPED(status) == 1);
174 TEST(WSTOPSIG(status) == SIGSTOP);
175 kill(pid, SIGCONT);
176 break;
177 }
178 close(fd);
179 return;
180 }
181
182 /**
183 * @tc.name : pread64
184 * @tc.desc : Exception scenarios for pread64
185 * @tc.level : Level 2
186 */
unistd_dynamic_chk_005(void)187 static void unistd_dynamic_chk_005(void)
188 {
189 struct sigaction sigabrt = {
190 .sa_handler = SignalHandler,
191 };
192 sigaction(SIGABRT, &sigabrt, NULL);
193
194 const int err = -1;
195 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
196 TEST(fd != err);
197 int status;
198
199 const int bufferSize = 2;
200 char buf[bufferSize];
201 size_t n = atoi("4");
202 int pid = fork();
203 switch (pid) {
204 case -1:
205 t_error("fork failed: %d\n", __LINE__);
206 break;
207 case 0:
208 pread64(fd, buf, n, 0);
209 exit(0);
210 default:
211 waitpid(pid, &status, WUNTRACED);
212 TEST(WIFEXITED(status) == 0);
213 TEST(WIFSTOPPED(status) == 1);
214 TEST(WSTOPSIG(status) == SIGSTOP);
215 kill(pid, SIGCONT);
216 break;
217 }
218 close(fd);
219 return;
220 }
221
222 /**
223 * @tc.name : pwrite64
224 * @tc.desc : Exception scenarios for pwrite64
225 * @tc.level : Level 2
226 */
unistd_dynamic_chk_006(void)227 static void unistd_dynamic_chk_006(void)
228 {
229 char fileName[] = "./unistd_dynamic_chk_003.txt";
230 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
231 TEST(fd != -1);
232
233 struct sigaction sigabrt = {
234 .sa_handler = SignalHandler,
235 };
236 sigaction(SIGABRT, &sigabrt, NULL);
237
238 char buf[] = "hello!";
239 size_t n = strlen(buf) + 2;
240 int status;
241 int pid = fork();
242 switch (pid) {
243 case -1:
244 t_error("fork failed: %d\n", __LINE__);
245 break;
246 case 0:
247 pwrite64(fd, buf, n, 0);
248 exit(0);
249 default:
250 waitpid(pid, &status, WUNTRACED);
251 TEST(WIFEXITED(status) == 0);
252 TEST(WIFSTOPPED(status) == 1);
253 TEST(WSTOPSIG(status) == SIGSTOP);
254 kill(pid, SIGCONT);
255 break;
256 }
257 close(fd);
258 return;
259 }
260
261 /**
262 * @tc.name : pwrite64
263 * @tc.desc : Exception scenarios for pwrite64
264 * @tc.level : Level 2
265 */
unistd_dynamic_chk_007(void)266 static void unistd_dynamic_chk_007(void)
267 {
268 char fileName[] = "./unistd_dynamic_chk_003.txt";
269 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
270 TEST(fd != -1);
271
272 struct sigaction sigabrt = {
273 .sa_handler = SignalHandler,
274 };
275 sigaction(SIGABRT, &sigabrt, NULL);
276
277 char buf[] = "hello!";
278 size_t n = strlen(buf) + SSIZE_MAX;
279 int status;
280 int pid = fork();
281 switch (pid) {
282 case -1:
283 t_error("fork failed: %d\n", __LINE__);
284 break;
285 case 0:
286 pwrite64(fd, buf, n, 0);
287 exit(0);
288 default:
289 waitpid(pid, &status, WUNTRACED);
290 TEST(WIFEXITED(status) == 0);
291 TEST(WIFSTOPPED(status) == 1);
292 TEST(WSTOPSIG(status) == SIGSTOP);
293 kill(pid, SIGCONT);
294 break;
295 }
296 close(fd);
297 return;
298 }
299
300
301 /**
302 * @tc.name : pwrite
303 * @tc.desc : Exception scenarios for pwrite
304 * @tc.level : Level 2
305 */
unistd_dynamic_chk_008(void)306 static void unistd_dynamic_chk_008(void)
307 {
308 const int err = -1;
309 char fileName[] = "./unistd_dynamic_chk_003.txt";
310 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
311 TEST(fd != err);
312
313 struct sigaction sigabrt = {
314 .sa_handler = SignalHandler,
315 };
316 sigaction(SIGABRT, &sigabrt, NULL);
317
318 char buf[] = "hello!";
319 size_t n = strlen(buf) + 2;
320 int status;
321 int pid = fork();
322 switch (pid) {
323 case -1:
324 t_error("fork failed: %d\n", __LINE__);
325 break;
326 case 0:
327 pwrite(fd, buf, n, 0);
328 exit(0);
329 default:
330 waitpid(pid, &status, WUNTRACED);
331 TEST(WIFEXITED(status) == 0);
332 TEST(WIFSTOPPED(status) == 1);
333 TEST(WSTOPSIG(status) == SIGSTOP);
334 kill(pid, SIGCONT);
335 break;
336 }
337 close(fd);
338 return;
339 }
340
341 /**
342 * @tc.name : pwrite
343 * @tc.desc : Exception scenarios for pwrite
344 * @tc.level : Level 2
345 */
unistd_dynamic_chk_009(void)346 static void unistd_dynamic_chk_009(void)
347 {
348 const int err = -1;
349 char fileName[] = "./unistd_dynamic_chk_003.txt";
350 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
351 TEST(fd != err);
352
353 struct sigaction sigabrt = {
354 .sa_handler = SignalHandler,
355 };
356 sigaction(SIGABRT, &sigabrt, NULL);
357
358 char buf[] = "hello!";
359 size_t n = strlen(buf) + SSIZE_MAX;
360 int status;
361 int pid = fork();
362 switch (pid) {
363 case -1:
364 t_error("fork failed: %d\n", __LINE__);
365 break;
366 case 0:
367 pwrite(fd, buf, n, 0);
368 exit(0);
369 default:
370 waitpid(pid, &status, WUNTRACED);
371 TEST(WIFEXITED(status) == 0);
372 TEST(WIFSTOPPED(status) == 1);
373 TEST(WSTOPSIG(status) == SIGSTOP);
374 kill(pid, SIGCONT);
375 break;
376 }
377 close(fd);
378 return;
379 }
380
381 /**
382 * @tc.name : read
383 * @tc.desc : Exception scenarios for read
384 * @tc.level : Level 2
385 */
unistd_dynamic_chk_010(void)386 static void unistd_dynamic_chk_010(void)
387 {
388 struct sigaction sigabrt = {
389 .sa_handler = SignalHandler,
390 };
391 sigaction(SIGABRT, &sigabrt, NULL);
392
393 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
394 int status;
395
396 const int bufferSize = 2;
397 char buf[bufferSize];
398 size_t n = atoi("4");
399 int pid = fork();
400 switch (pid) {
401 case -1:
402 t_error("fork failed: %d\n", __LINE__);
403 break;
404 case 0:
405 read(fd, buf, n);
406 exit(0);
407 default:
408 waitpid(pid, &status, WUNTRACED);
409 TEST(WIFEXITED(status) == 0);
410 TEST(WIFSTOPPED(status) == 1);
411 TEST(WSTOPSIG(status) == SIGSTOP);
412 kill(pid, SIGCONT);
413 break;
414 }
415 close(fd);
416 return;
417 }
418
419 /**
420 * @tc.name : read
421 * @tc.desc : Exception scenarios for read
422 * @tc.level : Level 2
423 */
unistd_dynamic_chk_011(void)424 static void unistd_dynamic_chk_011(void)
425 {
426 struct sigaction sigabrt = {
427 .sa_handler = SignalHandler,
428 };
429 sigaction(SIGABRT, &sigabrt, NULL);
430
431 int fd = open("/proc/version", O_RDWR | O_CREAT, 0777);
432 int status;
433
434 const int bufferSize = 2;
435 char buf[bufferSize];
436 size_t n = atoi("4") + SSIZE_MAX;
437 int pid = fork();
438 switch (pid) {
439 case -1:
440 t_error("fork failed: %d\n", __LINE__);
441 break;
442 case 0:
443 read(fd, buf, n);
444 exit(0);
445 default:
446 waitpid(pid, &status, WUNTRACED);
447 TEST(WIFEXITED(status) == 0);
448 TEST(WIFSTOPPED(status) == 1);
449 TEST(WSTOPSIG(status) == SIGSTOP);
450 kill(pid, SIGCONT);
451 break;
452 }
453 close(fd);
454 return;
455 }
456
457 /**
458 * @tc.name : write
459 * @tc.desc : Exception scenarios for write
460 * @tc.level : Level 2
461 */
unistd_dynamic_chk_012(void)462 static void unistd_dynamic_chk_012(void)
463 {
464 struct sigaction sigabrt = {
465 .sa_handler = SignalHandler,
466 };
467 sigaction(SIGABRT, &sigabrt, NULL);
468
469 const int err = -1;
470 char fileName[] = "./unistd_dynamic_chk_005.txt";
471 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
472 TEST(fd != err);
473
474 char buf[] = "hello!";
475 size_t n = strlen(buf) + 2;
476 int status;
477 int pid = fork();
478 switch (pid) {
479 case -1:
480 t_error("fork failed: %d\n", __LINE__);
481 break;
482 case 0:
483 write(fd, buf, n);
484 exit(0);
485 default:
486 waitpid(pid, &status, WUNTRACED);
487 TEST(WIFEXITED(status) == 0);
488 TEST(WIFSTOPPED(status) == 1);
489 TEST(WSTOPSIG(status) == SIGSTOP);
490 kill(pid, SIGCONT);
491 break;
492 }
493 close(fd);
494 return;
495 }
496
497 /**
498 * @tc.name : write
499 * @tc.desc : Exception scenarios for write
500 * @tc.level : Level 2
501 */
unistd_dynamic_chk_013(void)502 static void unistd_dynamic_chk_013(void)
503 {
504 struct sigaction sigabrt = {
505 .sa_handler = SignalHandler,
506 };
507 sigaction(SIGABRT, &sigabrt, NULL);
508
509 const int err = -1;
510 char fileName[] = "./unistd_dynamic_chk_005.txt";
511 int fd = open(fileName, O_RDWR | O_CREAT, 0777);
512 TEST(fd != err);
513
514 char buf[] = "hello!";
515 size_t n = strlen(buf) + SSIZE_MAX;
516 int status;
517 int pid = fork();
518 switch (pid) {
519 case -1:
520 t_error("fork failed: %d\n", __LINE__);
521 break;
522 case 0:
523 write(fd, buf, n);
524 exit(0);
525 default:
526 waitpid(pid, &status, WUNTRACED);
527 TEST(WIFEXITED(status) == 0);
528 TEST(WIFSTOPPED(status) == 1);
529 TEST(WSTOPSIG(status) == SIGSTOP);
530 kill(pid, SIGCONT);
531 break;
532 }
533 close(fd);
534 return;
535 }
536
537 /**
538 * @tc.name : readlink
539 * @tc.desc : Exception scenarios for readlink
540 * @tc.level : Level 2
541 */
unistd_dynamic_chk_014(void)542 static void unistd_dynamic_chk_014(void)
543 {
544 struct sigaction sigabrt = {
545 .sa_handler = SignalHandler,
546 };
547 sigaction(SIGABRT, &sigabrt, NULL);
548
549 char path[] = "/dev/null";
550
551 const int bufferSize = 1;
552 char buf[bufferSize];
553 size_t n = atoi("2");
554 int status;
555 int pid = fork();
556 switch (pid) {
557 case -1:
558 t_error("fork failed: %d\n", __LINE__);
559 break;
560 case 0:
561 readlink(path, buf, n);
562 exit(0);
563 default:
564 waitpid(pid, &status, WUNTRACED);
565 TEST(WIFEXITED(status) == 0);
566 TEST(WIFSTOPPED(status) == 1);
567 TEST(WSTOPSIG(status) == SIGSTOP);
568 kill(pid, SIGCONT);
569 break;
570 }
571 return;
572 }
573
574 /**
575 * @tc.name : readlink
576 * @tc.desc : Exception scenarios for readlink
577 * @tc.level : Level 2
578 */
unistd_dynamic_chk_015(void)579 static void unistd_dynamic_chk_015(void)
580 {
581 struct sigaction sigabrt = {
582 .sa_handler = SignalHandler,
583 };
584 sigaction(SIGABRT, &sigabrt, NULL);
585
586 char path[] = "/dev/null";
587
588 const int bufferSize = 1;
589 char buf[bufferSize];
590 size_t n = atoi("2") + SSIZE_MAX;
591 int status;
592 int pid = fork();
593 switch (pid) {
594 case -1:
595 t_error("fork failed: %d\n", __LINE__);
596 break;
597 case 0:
598 readlink(path, buf, n);
599 exit(0);
600 default:
601 waitpid(pid, &status, WUNTRACED);
602 TEST(WIFEXITED(status) == 0);
603 TEST(WIFSTOPPED(status) == 1);
604 TEST(WSTOPSIG(status) == SIGSTOP);
605 kill(pid, SIGCONT);
606 break;
607 }
608 return;
609 }
610 /**
611 * @tc.name : readlinkat
612 * @tc.desc : Exception scenarios for readlinkat
613 * @tc.level : Level 2
614 */
unistd_dynamic_chk_016(void)615 static void unistd_dynamic_chk_016(void)
616 {
617 struct sigaction sigabrt = {
618 .sa_handler = SignalHandler,
619 };
620 sigaction(SIGABRT, &sigabrt, NULL);
621
622 char path[] = "/dev/null";
623
624 const int bufferSize = 1;
625 char buf[bufferSize];
626
627 size_t n = atoi("2");
628 int status;
629 int pid = fork();
630 switch (pid) {
631 case -1:
632 t_error("fork failed: %d\n", __LINE__);
633 break;
634 case 0:
635 readlinkat(AT_FDCWD, path, buf, n);
636 exit(0);
637 default:
638 waitpid(pid, &status, WUNTRACED);
639 TEST(WIFEXITED(status) == 0);
640 TEST(WIFSTOPPED(status) == 1);
641 TEST(WSTOPSIG(status) == SIGSTOP);
642 kill(pid, SIGCONT);
643 break;
644 }
645 return;
646 }
647
648 /**
649 * @tc.name : readlinkat
650 * @tc.desc : Exception scenarios for readlinkat
651 * @tc.level : Level 2
652 */
unistd_dynamic_chk_017(void)653 static void unistd_dynamic_chk_017(void)
654 {
655 struct sigaction sigabrt = {
656 .sa_handler = SignalHandler,
657 };
658 sigaction(SIGABRT, &sigabrt, NULL);
659
660 char path[] = "/dev/null";
661
662 const int bufferSize = 1;
663 char buf[bufferSize];
664
665 size_t n = atoi("1") + SSIZE_MAX;
666 int status;
667 int pid = fork();
668 switch (pid) {
669 case -1:
670 t_error("fork failed: %d\n", __LINE__);
671 break;
672 case 0:
673 readlinkat(AT_FDCWD, path, buf, n);
674 exit(0);
675 default:
676 waitpid(pid, &status, WUNTRACED);
677 TEST(WIFEXITED(status) == 0);
678 TEST(WIFSTOPPED(status) == 1);
679 TEST(WSTOPSIG(status) == SIGSTOP);
680 kill(pid, SIGCONT);
681 break;
682 }
683 return;
684 }
main(int argc,char * argv[])685 int main(int argc, char *argv[])
686 {
687 remove_all_special_handler(SIGABRT);
688 unistd_dynamic_chk_001();
689 unistd_dynamic_chk_002();
690 unistd_dynamic_chk_003();
691 unistd_dynamic_chk_004();
692 unistd_dynamic_chk_005();
693 unistd_dynamic_chk_006();
694 unistd_dynamic_chk_007();
695 unistd_dynamic_chk_008();
696 unistd_dynamic_chk_009();
697 unistd_dynamic_chk_010();
698 unistd_dynamic_chk_011();
699 unistd_dynamic_chk_012();
700 unistd_dynamic_chk_013();
701 unistd_dynamic_chk_014();
702 unistd_dynamic_chk_015();
703 unistd_dynamic_chk_016();
704 unistd_dynamic_chk_017();
705 return t_status;
706 }