string: Disable stack protector for memset in early static initialization
[glibc.git] / nptl / tst-setuid1.c
blobcf1bbf363502a84d5c41a26adf31c94a41e5fdba
1 /* Copyright (C) 2004-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 #include <pthread.h>
19 #include <pwd.h>
20 #include <grp.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
27 static pthread_barrier_t b3, b4;
28 static uid_t prev_ruid, prev_euid, prev_suid, nobody_uid;
29 static gid_t prev_rgid, prev_egid, prev_sgid, nobody_gid;
30 enum ACTION { PREPARE, SET, CHECK_BEFORE, CHECK_AFTER };
31 #define TESTNO(arg) ((long int) (arg) & 0xff)
32 #define THREADNO(arg) ((long int) (arg) >> 8)
35 static void
36 check_prev_uid (int tno)
38 uid_t ruid, euid, suid;
39 if (getresuid (&ruid, &euid, &suid) < 0)
41 printf ("getresuid failed: %d %m\n", tno);
42 exit (1);
45 if (ruid != prev_ruid || euid != prev_euid || suid != prev_suid)
47 printf ("uids before in %d (%d %d %d) != (%d %d %d)\n", tno,
48 ruid, euid, suid, prev_ruid, prev_euid, prev_suid);
49 exit (1);
54 static void
55 check_prev_gid (int tno)
57 gid_t rgid, egid, sgid;
58 if (getresgid (&rgid, &egid, &sgid) < 0)
60 printf ("getresgid failed: %d %m\n", tno);
61 exit (1);
64 if (rgid != prev_rgid || egid != prev_egid || sgid != prev_sgid)
66 printf ("gids before in %d (%d %d %d) != (%d %d %d)\n", tno,
67 rgid, egid, sgid, prev_rgid, prev_egid, prev_sgid);
68 exit (1);
73 static void
74 test_setuid1 (enum ACTION action, int tno)
76 if (action == PREPARE)
77 return;
79 if (action != CHECK_AFTER)
80 check_prev_uid (tno);
82 if (action == SET && setuid (nobody_uid) < 0)
84 printf ("setuid failed: %m\n");
85 exit (1);
88 if (action != CHECK_BEFORE)
90 uid_t ruid, euid, suid;
91 if (getresuid (&ruid, &euid, &suid) < 0)
93 printf ("getresuid failed: %d %m\n", tno);
94 exit (1);
97 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
99 printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
100 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
101 exit (1);
107 static void
108 test_setuid2 (enum ACTION action, int tno)
110 if (action == PREPARE)
112 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
114 printf ("setresuid failed: %m\n");
115 exit (1);
118 prev_ruid = nobody_uid;
119 prev_euid = nobody_uid;
120 return;
123 if (action != CHECK_AFTER)
124 check_prev_uid (tno);
126 if (action == SET && setuid (prev_suid) < 0)
128 printf ("setuid failed: %m\n");
129 exit (1);
132 if (action != CHECK_BEFORE)
134 uid_t ruid, euid, suid;
135 if (getresuid (&ruid, &euid, &suid) < 0)
137 printf ("getresuid failed: %d %m\n", tno);
138 exit (1);
141 if (ruid != nobody_uid || euid != prev_suid || suid != prev_suid)
143 printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
144 ruid, euid, suid, nobody_uid, prev_suid, prev_suid);
145 exit (1);
151 static void
152 test_seteuid1 (enum ACTION action, int tno)
154 if (action == PREPARE)
155 return;
157 if (action != CHECK_AFTER)
158 check_prev_uid (tno);
160 if (action == SET && seteuid (nobody_uid) < 0)
162 printf ("seteuid failed: %m\n");
163 exit (1);
166 if (action != CHECK_BEFORE)
168 uid_t ruid, euid, suid;
169 if (getresuid (&ruid, &euid, &suid) < 0)
171 printf ("getresuid failed: %d %m\n", tno);
172 exit (1);
175 if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
177 printf ("after seteuid %d (%d %d %d) != (%d %d %d)\n", tno,
178 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
179 exit (1);
185 static void
186 test_seteuid2 (enum ACTION action, int tno)
188 if (action == PREPARE)
190 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
192 printf ("setresuid failed: %m\n");
193 exit (1);
196 prev_ruid = nobody_uid;
197 prev_euid = nobody_uid;
198 nobody_uid = prev_suid;
199 return;
202 test_seteuid1 (action, tno);
206 static void
207 test_setreuid1 (enum ACTION action, int tno)
209 if (action == PREPARE)
210 return;
212 if (action != CHECK_AFTER)
213 check_prev_uid (tno);
215 if (action == SET && setreuid (-1, nobody_uid) < 0)
217 printf ("setreuid failed: %m\n");
218 exit (1);
221 if (action != CHECK_BEFORE)
223 uid_t ruid, euid, suid, esuid;
224 if (getresuid (&ruid, &euid, &suid) < 0)
226 printf ("getresuid failed: %d %m\n", tno);
227 exit (1);
230 if (prev_ruid != nobody_uid)
231 esuid = nobody_uid;
232 else
233 esuid = prev_suid;
235 if (ruid != prev_ruid || euid != nobody_uid || suid != esuid)
237 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
238 ruid, euid, suid, prev_ruid, nobody_uid, esuid);
239 exit (1);
245 static void
246 test_setreuid2 (enum ACTION action, int tno)
248 if (action == PREPARE)
249 return;
251 if (action != CHECK_AFTER)
252 check_prev_uid (tno);
254 if (action == SET && setreuid (nobody_uid, -1) < 0)
256 printf ("setreuid failed: %m\n");
257 exit (1);
260 if (action != CHECK_BEFORE)
262 uid_t ruid, euid, suid;
263 if (getresuid (&ruid, &euid, &suid) < 0)
265 printf ("getresuid failed: %d %m\n", tno);
266 exit (1);
269 if (ruid != nobody_uid || euid != prev_euid || suid != prev_euid)
271 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
272 ruid, euid, suid, nobody_uid, prev_euid, prev_euid);
273 exit (1);
279 static void
280 test_setreuid3 (enum ACTION action, int tno)
282 if (action == PREPARE)
283 return;
285 if (action != CHECK_AFTER)
286 check_prev_uid (tno);
288 if (action == SET && setreuid (nobody_uid, nobody_uid) < 0)
290 printf ("setreuid failed: %m\n");
291 exit (1);
294 if (action != CHECK_BEFORE)
296 uid_t ruid, euid, suid;
297 if (getresuid (&ruid, &euid, &suid) < 0)
299 printf ("getresuid failed: %d %m\n", tno);
300 exit (1);
303 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
305 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
306 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
307 exit (1);
313 static void
314 test_setreuid4 (enum ACTION action, int tno)
316 if (action == PREPARE)
318 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
320 printf ("setresuid failed: %m\n");
321 exit (1);
324 prev_ruid = nobody_uid;
325 prev_euid = nobody_uid;
326 nobody_uid = prev_suid;
327 return;
330 test_setreuid1 (action, tno);
334 static void
335 test_setresuid1 (enum ACTION action, int tno)
337 if (action == PREPARE)
338 return;
340 if (action != CHECK_AFTER)
341 check_prev_uid (tno);
343 if (action == SET && setresuid (-1, nobody_uid, -1) < 0)
345 printf ("setresuid failed: %m\n");
346 exit (1);
349 if (action != CHECK_BEFORE)
351 uid_t ruid, euid, suid;
352 if (getresuid (&ruid, &euid, &suid) < 0)
354 printf ("getresuid failed: %d %m\n", tno);
355 exit (1);
358 if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
360 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
361 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
362 exit (1);
368 static void
369 test_setresuid2 (enum ACTION action, int tno)
371 if (action == PREPARE)
372 return;
374 if (action != CHECK_AFTER)
375 check_prev_uid (tno);
377 if (action == SET && setresuid (prev_euid, nobody_uid, nobody_uid) < 0)
379 printf ("setresuid failed: %m\n");
380 exit (1);
383 if (action != CHECK_BEFORE)
385 uid_t ruid, euid, suid;
386 if (getresuid (&ruid, &euid, &suid) < 0)
388 printf ("getresuid failed: %d %m\n", tno);
389 exit (1);
392 if (ruid != prev_euid || euid != nobody_uid || suid != nobody_uid)
394 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
395 ruid, euid, suid, prev_euid, nobody_uid, nobody_uid);
396 exit (1);
402 static void
403 test_setresuid3 (enum ACTION action, int tno)
405 if (action == PREPARE)
406 return;
408 if (action != CHECK_AFTER)
409 check_prev_uid (tno);
411 if (action == SET && setresuid (nobody_uid, nobody_uid, nobody_uid) < 0)
413 printf ("setresuid failed: %m\n");
414 exit (1);
417 if (action != CHECK_BEFORE)
419 uid_t ruid, euid, suid;
420 if (getresuid (&ruid, &euid, &suid) < 0)
422 printf ("getresuid failed: %d %m\n", tno);
423 exit (1);
426 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
428 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
429 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
430 exit (1);
436 static void
437 test_setresuid4 (enum ACTION action, int tno)
439 if (action == PREPARE)
441 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
443 printf ("setresuid failed: %m\n");
444 exit (1);
447 prev_ruid = nobody_uid;
448 prev_euid = nobody_uid;
449 nobody_uid = prev_suid;
450 return;
453 test_setresuid1 (action, tno);
457 static void
458 test_setgid1 (enum ACTION action, int tno)
460 if (action == PREPARE)
461 return;
463 if (action != CHECK_AFTER)
464 check_prev_gid (tno);
466 if (action == SET && setgid (nobody_gid) < 0)
468 printf ("setgid failed: %m\n");
469 exit (1);
472 if (action != CHECK_BEFORE)
474 gid_t rgid, egid, sgid;
475 if (getresgid (&rgid, &egid, &sgid) < 0)
477 printf ("getresgid failed: %d %m\n", tno);
478 exit (1);
481 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
483 printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
484 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
485 exit (1);
491 static void
492 test_setgid2 (enum ACTION action, int tno)
494 if (action == PREPARE)
496 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
498 printf ("setresgid failed: %m\n");
499 exit (1);
502 prev_rgid = nobody_gid;
503 prev_egid = nobody_gid;
505 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
507 printf ("setresuid failed: %m\n");
508 exit (1);
511 prev_ruid = nobody_uid;
512 prev_euid = nobody_uid;
513 return;
516 if (action != CHECK_AFTER)
517 check_prev_gid (tno);
519 if (action == SET && setgid (prev_sgid) < 0)
521 printf ("setgid failed: %m\n");
522 exit (1);
525 if (action != CHECK_BEFORE)
527 gid_t rgid, egid, sgid;
528 if (getresgid (&rgid, &egid, &sgid) < 0)
530 printf ("getresgid failed: %d %m\n", tno);
531 exit (1);
534 if (rgid != nobody_gid || egid != prev_sgid || sgid != prev_sgid)
536 printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
537 rgid, egid, sgid, nobody_gid, prev_sgid, prev_sgid);
538 exit (1);
544 static void
545 test_setegid1 (enum ACTION action, int tno)
547 if (action == PREPARE)
548 return;
550 if (action != CHECK_AFTER)
551 check_prev_gid (tno);
553 if (action == SET && setegid (nobody_gid) < 0)
555 printf ("setegid failed: %m\n");
556 exit (1);
559 if (action != CHECK_BEFORE)
561 gid_t rgid, egid, sgid;
562 if (getresgid (&rgid, &egid, &sgid) < 0)
564 printf ("getresgid failed: %d %m\n", tno);
565 exit (1);
568 if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
570 printf ("after setegid %d (%d %d %d) != (%d %d %d)\n", tno,
571 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
572 exit (1);
578 static void
579 test_setegid2 (enum ACTION action, int tno)
581 if (action == PREPARE)
583 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
585 printf ("setresgid failed: %m\n");
586 exit (1);
589 prev_rgid = nobody_gid;
590 prev_egid = nobody_gid;
591 nobody_gid = prev_sgid;
592 return;
595 test_setegid1 (action, tno);
599 static void
600 test_setregid1 (enum ACTION action, int tno)
602 if (action == PREPARE)
603 return;
605 if (action != CHECK_AFTER)
606 check_prev_gid (tno);
608 if (action == SET && setregid (-1, nobody_gid) < 0)
610 printf ("setregid failed: %m\n");
611 exit (1);
614 if (action != CHECK_BEFORE)
616 gid_t rgid, egid, sgid, esgid;
617 if (getresgid (&rgid, &egid, &sgid) < 0)
619 printf ("getresgid failed: %d %m\n", tno);
620 exit (1);
623 if (prev_rgid != nobody_gid)
624 esgid = nobody_gid;
625 else
626 esgid = prev_sgid;
628 if (rgid != prev_rgid || egid != nobody_gid || sgid != esgid)
630 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
631 rgid, egid, sgid, prev_rgid, nobody_gid, esgid);
632 exit (1);
638 static void
639 test_setregid2 (enum ACTION action, int tno)
641 if (action == PREPARE)
642 return;
644 if (action != CHECK_AFTER)
645 check_prev_gid (tno);
647 if (action == SET && setregid (nobody_gid, -1) < 0)
649 printf ("setregid failed: %m\n");
650 exit (1);
653 if (action != CHECK_BEFORE)
655 gid_t rgid, egid, sgid;
656 if (getresgid (&rgid, &egid, &sgid) < 0)
658 printf ("getresgid failed: %d %m\n", tno);
659 exit (1);
662 if (rgid != nobody_gid || egid != prev_egid || sgid != prev_egid)
664 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
665 rgid, egid, sgid, nobody_gid, prev_egid, prev_egid);
666 exit (1);
672 static void
673 test_setregid3 (enum ACTION action, int tno)
675 if (action == PREPARE)
676 return;
678 if (action != CHECK_AFTER)
679 check_prev_gid (tno);
681 if (action == SET && setregid (nobody_gid, nobody_gid) < 0)
683 printf ("setregid failed: %m\n");
684 exit (1);
687 if (action != CHECK_BEFORE)
689 gid_t rgid, egid, sgid;
690 if (getresgid (&rgid, &egid, &sgid) < 0)
692 printf ("getresgid failed: %d %m\n", tno);
693 exit (1);
696 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
698 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
699 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
700 exit (1);
706 static void
707 test_setregid4 (enum ACTION action, int tno)
709 if (action == PREPARE)
711 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
713 printf ("setresgid failed: %m\n");
714 exit (1);
717 prev_rgid = nobody_gid;
718 prev_egid = nobody_gid;
719 nobody_gid = prev_sgid;
720 return;
723 test_setregid1 (action, tno);
727 static void
728 test_setresgid1 (enum ACTION action, int tno)
730 if (action == PREPARE)
731 return;
733 if (action != CHECK_AFTER)
734 check_prev_gid (tno);
736 if (action == SET && setresgid (-1, nobody_gid, -1) < 0)
738 printf ("setresgid failed: %m\n");
739 exit (1);
742 if (action != CHECK_BEFORE)
744 gid_t rgid, egid, sgid;
745 if (getresgid (&rgid, &egid, &sgid) < 0)
747 printf ("getresgid failed: %d %m\n", tno);
748 exit (1);
751 if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
753 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
754 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
755 exit (1);
761 static void
762 test_setresgid2 (enum ACTION action, int tno)
764 if (action == PREPARE)
765 return;
767 if (action != CHECK_AFTER)
768 check_prev_gid (tno);
770 if (action == SET && setresgid (prev_egid, nobody_gid, nobody_gid) < 0)
772 printf ("setresgid failed: %m\n");
773 exit (1);
776 if (action != CHECK_BEFORE)
778 gid_t rgid, egid, sgid;
779 if (getresgid (&rgid, &egid, &sgid) < 0)
781 printf ("getresgid failed: %d %m\n", tno);
782 exit (1);
785 if (rgid != prev_egid || egid != nobody_gid || sgid != nobody_gid)
787 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
788 rgid, egid, sgid, prev_egid, nobody_gid, nobody_gid);
789 exit (1);
795 static void
796 test_setresgid3 (enum ACTION action, int tno)
798 if (action == PREPARE)
799 return;
801 if (action != CHECK_AFTER)
802 check_prev_gid (tno);
804 if (action == SET && setresgid (nobody_gid, nobody_gid, nobody_gid) < 0)
806 printf ("setresgid failed: %m\n");
807 exit (1);
810 if (action != CHECK_BEFORE)
812 gid_t rgid, egid, sgid;
813 if (getresgid (&rgid, &egid, &sgid) < 0)
815 printf ("getresgid failed: %d %m\n", tno);
816 exit (1);
819 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
821 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
822 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
823 exit (1);
829 static void
830 test_setresgid4 (enum ACTION action, int tno)
832 if (action == PREPARE)
834 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
836 printf ("setresgid failed: %m\n");
837 exit (1);
840 prev_rgid = nobody_gid;
841 prev_egid = nobody_gid;
842 nobody_gid = prev_sgid;
843 return;
846 test_setresgid1 (action, tno);
850 static struct setuid_test
852 const char *name;
853 void (*test) (enum ACTION, int tno);
854 } setuid_tests[] =
856 { "setuid1", test_setuid1 },
857 { "setuid2", test_setuid2 },
858 { "seteuid1", test_seteuid1 },
859 { "seteuid2", test_seteuid2 },
860 { "setreuid1", test_setreuid1 },
861 { "setreuid2", test_setreuid2 },
862 { "setreuid3", test_setreuid3 },
863 { "setreuid4", test_setreuid4 },
864 { "setresuid1", test_setresuid1 },
865 { "setresuid2", test_setresuid2 },
866 { "setresuid3", test_setresuid3 },
867 { "setresuid4", test_setresuid4 },
868 { "setgid1", test_setgid1 },
869 { "setgid2", test_setgid2 },
870 { "setegid1", test_setegid1 },
871 { "setegid2", test_setegid2 },
872 { "setregid1", test_setregid1 },
873 { "setregid2", test_setregid2 },
874 { "setregid3", test_setregid3 },
875 { "setregid4", test_setregid4 },
876 { "setresgid1", test_setresgid1 },
877 { "setresgid2", test_setresgid2 },
878 { "setresgid3", test_setresgid3 },
879 { "setresgid4", test_setresgid4 }
883 static void *
884 tf2 (void *arg)
886 int e = pthread_barrier_wait (&b4);
887 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
889 puts ("barrier_wait failed");
890 exit (1);
893 setuid_tests[TESTNO (arg)].test (CHECK_AFTER, THREADNO (arg));
894 return NULL;
898 static void *
899 tf (void *arg)
901 setuid_tests[TESTNO (arg)].test (CHECK_BEFORE, THREADNO (arg));
903 int e = pthread_barrier_wait (&b3);
904 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
906 puts ("barrier_wait failed");
907 exit (1);
910 return tf2 (arg);
914 static int
915 do_one_test (long int testno)
917 printf ("%s test\n", setuid_tests[testno].name);
919 pid_t pid = fork ();
920 if (pid == 0)
922 setuid_tests[testno].test (PREPARE, 0);
923 setuid_tests[testno].test (SET, 0);
924 exit (0);
927 if (pid < 0)
929 printf ("fork failed: %m\n");
930 exit (1);
933 int status;
934 if (waitpid (pid, &status, 0) < 0)
936 printf ("waitpid failed: %m\n");
937 exit (1);
940 if (!WIFEXITED (status))
942 puts ("child did not exit");
943 exit (1);
946 if (WEXITSTATUS (status))
948 printf ("skipping %s test\n", setuid_tests[testno].name);
949 return 0;
952 pid = fork ();
953 if (pid == 0)
955 setuid_tests[testno].test (PREPARE, 0);
957 pthread_t th;
958 int e = pthread_create (&th, NULL, tf, (void *) (testno | 0x100L));
959 if (e != 0)
961 printf ("create failed: %m\n");
962 exit (1);
965 pthread_t th2;
966 e = pthread_create (&th2, NULL, tf, (void *) (testno | 0x200L));
967 if (e != 0)
969 printf ("create failed: %m\n");
970 exit (1);
973 e = pthread_barrier_wait (&b3);
974 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
976 puts ("barrier_wait failed");
977 exit (1);
980 setuid_tests[testno].test (SET, 0);
982 pthread_t th3;
983 e = pthread_create (&th3, NULL, tf2, (void *) (testno | 0x300L));
984 if (e != 0)
986 printf ("create failed: %m\n");
987 exit (1);
990 e = pthread_barrier_wait (&b4);
991 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
993 puts ("barrier_wait failed");
994 exit (1);
997 exit (0);
1000 if (pid < 0)
1002 printf ("fork failed: %m\n");
1003 exit (1);
1006 if (waitpid (pid, &status, 0) < 0)
1008 printf ("waitpid failed: %m\n");
1009 exit (1);
1012 if (!WIFEXITED (status))
1014 puts ("second child did not exit");
1015 exit (1);
1018 if (WEXITSTATUS (status))
1019 exit (WEXITSTATUS (status));
1021 return 0;
1025 static int
1026 do_test (void)
1028 struct passwd *pwd = getpwnam ("nobody");
1029 if (pwd == NULL)
1031 puts ("User nobody doesn't exist");
1032 return 0;
1034 nobody_uid = pwd->pw_uid;
1035 nobody_gid = pwd->pw_gid;
1037 if (getresuid (&prev_ruid, &prev_euid, &prev_suid) < 0)
1039 printf ("getresuid failed: %m\n");
1040 exit (1);
1043 if (getresgid (&prev_rgid, &prev_egid, &prev_sgid) < 0)
1045 printf ("getresgid failed: %m\n");
1046 exit (1);
1049 if (prev_ruid == nobody_uid || prev_euid == nobody_uid
1050 || prev_suid == nobody_uid)
1052 puts ("already running as user nobody, skipping tests");
1053 exit (0);
1056 if (prev_rgid == nobody_gid || prev_egid == nobody_gid
1057 || prev_sgid == nobody_gid)
1059 puts ("already running as group nobody, skipping tests");
1060 exit (0);
1063 if (pthread_barrier_init (&b3, NULL, 3) != 0)
1065 puts ("barrier_init failed");
1066 exit (1);
1069 if (pthread_barrier_init (&b4, NULL, 4) != 0)
1071 puts ("barrier_init failed");
1072 exit (1);
1075 for (unsigned long int testno = 0;
1076 testno < sizeof (setuid_tests) / sizeof (setuid_tests[0]);
1077 ++testno)
1078 do_one_test (testno);
1079 return 0;
1082 #define TEST_FUNCTION do_test ()
1083 #include "../test-skeleton.c"