Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* Copyright (C) 2004-2019 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Jakub Jelinek <jaku@redhat.com>, 2004.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19#include <pthread.h>
20#include <pwd.h>
21#include <grp.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <sys/wait.h>
25#include <unistd.h>
26
27
28static pthread_barrier_t b3, b4;
29static uid_t prev_ruid, prev_euid, prev_suid, nobody_uid;
30static gid_t prev_rgid, prev_egid, prev_sgid, nobody_gid;
31enum ACTION { PREPARE, SET, CHECK_BEFORE, CHECK_AFTER };
32#define TESTNO(arg) ((long int) (arg) & 0xff)
33#define THREADNO(arg) ((long int) (arg) >> 8)
34
35
36static void
37check_prev_uid (int tno)
38{
39 uid_t ruid, euid, suid;
40 if (getresuid (&ruid, &euid, &suid) < 0)
41 {
42 printf ("getresuid failed: %d %m\n", tno);
43 exit (1);
44 }
45
46 if (ruid != prev_ruid || euid != prev_euid || suid != prev_suid)
47 {
48 printf ("uids before in %d (%d %d %d) != (%d %d %d)\n", tno,
49 ruid, euid, suid, prev_ruid, prev_euid, prev_suid);
50 exit (1);
51 }
52}
53
54
55static void
56check_prev_gid (int tno)
57{
58 gid_t rgid, egid, sgid;
59 if (getresgid (&rgid, &egid, &sgid) < 0)
60 {
61 printf ("getresgid failed: %d %m\n", tno);
62 exit (1);
63 }
64
65 if (rgid != prev_rgid || egid != prev_egid || sgid != prev_sgid)
66 {
67 printf ("gids before in %d (%d %d %d) != (%d %d %d)\n", tno,
68 rgid, egid, sgid, prev_rgid, prev_egid, prev_sgid);
69 exit (1);
70 }
71}
72
73
74static void
75test_setuid1 (enum ACTION action, int tno)
76{
77 if (action == PREPARE)
78 return;
79
80 if (action != CHECK_AFTER)
81 check_prev_uid (tno);
82
83 if (action == SET && setuid (nobody_uid) < 0)
84 {
85 printf ("setuid failed: %m\n");
86 exit (1);
87 }
88
89 if (action != CHECK_BEFORE)
90 {
91 uid_t ruid, euid, suid;
92 if (getresuid (&ruid, &euid, &suid) < 0)
93 {
94 printf ("getresuid failed: %d %m\n", tno);
95 exit (1);
96 }
97
98 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
99 {
100 printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
101 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
102 exit (1);
103 }
104 }
105}
106
107
108static void
109test_setuid2 (enum ACTION action, int tno)
110{
111 if (action == PREPARE)
112 {
113 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
114 {
115 printf ("setresuid failed: %m\n");
116 exit (1);
117 }
118
119 prev_ruid = nobody_uid;
120 prev_euid = nobody_uid;
121 return;
122 }
123
124 if (action != CHECK_AFTER)
125 check_prev_uid (tno);
126
127 if (action == SET && setuid (prev_suid) < 0)
128 {
129 printf ("setuid failed: %m\n");
130 exit (1);
131 }
132
133 if (action != CHECK_BEFORE)
134 {
135 uid_t ruid, euid, suid;
136 if (getresuid (&ruid, &euid, &suid) < 0)
137 {
138 printf ("getresuid failed: %d %m\n", tno);
139 exit (1);
140 }
141
142 if (ruid != nobody_uid || euid != prev_suid || suid != prev_suid)
143 {
144 printf ("after setuid %d (%d %d %d) != (%d %d %d)\n", tno,
145 ruid, euid, suid, nobody_uid, prev_suid, prev_suid);
146 exit (1);
147 }
148 }
149}
150
151
152static void
153test_seteuid1 (enum ACTION action, int tno)
154{
155 if (action == PREPARE)
156 return;
157
158 if (action != CHECK_AFTER)
159 check_prev_uid (tno);
160
161 if (action == SET && seteuid (nobody_uid) < 0)
162 {
163 printf ("seteuid failed: %m\n");
164 exit (1);
165 }
166
167 if (action != CHECK_BEFORE)
168 {
169 uid_t ruid, euid, suid;
170 if (getresuid (&ruid, &euid, &suid) < 0)
171 {
172 printf ("getresuid failed: %d %m\n", tno);
173 exit (1);
174 }
175
176 if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
177 {
178 printf ("after seteuid %d (%d %d %d) != (%d %d %d)\n", tno,
179 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
180 exit (1);
181 }
182 }
183}
184
185
186static void
187test_seteuid2 (enum ACTION action, int tno)
188{
189 if (action == PREPARE)
190 {
191 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
192 {
193 printf ("setresuid failed: %m\n");
194 exit (1);
195 }
196
197 prev_ruid = nobody_uid;
198 prev_euid = nobody_uid;
199 nobody_uid = prev_suid;
200 return;
201 }
202
203 test_seteuid1 (action, tno);
204}
205
206
207static void
208test_setreuid1 (enum ACTION action, int tno)
209{
210 if (action == PREPARE)
211 return;
212
213 if (action != CHECK_AFTER)
214 check_prev_uid (tno);
215
216 if (action == SET && setreuid (-1, nobody_uid) < 0)
217 {
218 printf ("setreuid failed: %m\n");
219 exit (1);
220 }
221
222 if (action != CHECK_BEFORE)
223 {
224 uid_t ruid, euid, suid, esuid;
225 if (getresuid (&ruid, &euid, &suid) < 0)
226 {
227 printf ("getresuid failed: %d %m\n", tno);
228 exit (1);
229 }
230
231 if (prev_ruid != nobody_uid)
232 esuid = nobody_uid;
233 else
234 esuid = prev_suid;
235
236 if (ruid != prev_ruid || euid != nobody_uid || suid != esuid)
237 {
238 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
239 ruid, euid, suid, prev_ruid, nobody_uid, esuid);
240 exit (1);
241 }
242 }
243}
244
245
246static void
247test_setreuid2 (enum ACTION action, int tno)
248{
249 if (action == PREPARE)
250 return;
251
252 if (action != CHECK_AFTER)
253 check_prev_uid (tno);
254
255 if (action == SET && setreuid (nobody_uid, -1) < 0)
256 {
257 printf ("setreuid failed: %m\n");
258 exit (1);
259 }
260
261 if (action != CHECK_BEFORE)
262 {
263 uid_t ruid, euid, suid;
264 if (getresuid (&ruid, &euid, &suid) < 0)
265 {
266 printf ("getresuid failed: %d %m\n", tno);
267 exit (1);
268 }
269
270 if (ruid != nobody_uid || euid != prev_euid || suid != prev_euid)
271 {
272 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
273 ruid, euid, suid, nobody_uid, prev_euid, prev_euid);
274 exit (1);
275 }
276 }
277}
278
279
280static void
281test_setreuid3 (enum ACTION action, int tno)
282{
283 if (action == PREPARE)
284 return;
285
286 if (action != CHECK_AFTER)
287 check_prev_uid (tno);
288
289 if (action == SET && setreuid (nobody_uid, nobody_uid) < 0)
290 {
291 printf ("setreuid failed: %m\n");
292 exit (1);
293 }
294
295 if (action != CHECK_BEFORE)
296 {
297 uid_t ruid, euid, suid;
298 if (getresuid (&ruid, &euid, &suid) < 0)
299 {
300 printf ("getresuid failed: %d %m\n", tno);
301 exit (1);
302 }
303
304 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
305 {
306 printf ("after setreuid %d (%d %d %d) != (%d %d %d)\n", tno,
307 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
308 exit (1);
309 }
310 }
311}
312
313
314static void
315test_setreuid4 (enum ACTION action, int tno)
316{
317 if (action == PREPARE)
318 {
319 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
320 {
321 printf ("setresuid failed: %m\n");
322 exit (1);
323 }
324
325 prev_ruid = nobody_uid;
326 prev_euid = nobody_uid;
327 nobody_uid = prev_suid;
328 return;
329 }
330
331 test_setreuid1 (action, tno);
332}
333
334
335static void
336test_setresuid1 (enum ACTION action, int tno)
337{
338 if (action == PREPARE)
339 return;
340
341 if (action != CHECK_AFTER)
342 check_prev_uid (tno);
343
344 if (action == SET && setresuid (-1, nobody_uid, -1) < 0)
345 {
346 printf ("setresuid failed: %m\n");
347 exit (1);
348 }
349
350 if (action != CHECK_BEFORE)
351 {
352 uid_t ruid, euid, suid;
353 if (getresuid (&ruid, &euid, &suid) < 0)
354 {
355 printf ("getresuid failed: %d %m\n", tno);
356 exit (1);
357 }
358
359 if (ruid != prev_ruid || euid != nobody_uid || suid != prev_suid)
360 {
361 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
362 ruid, euid, suid, prev_ruid, nobody_uid, prev_suid);
363 exit (1);
364 }
365 }
366}
367
368
369static void
370test_setresuid2 (enum ACTION action, int tno)
371{
372 if (action == PREPARE)
373 return;
374
375 if (action != CHECK_AFTER)
376 check_prev_uid (tno);
377
378 if (action == SET && setresuid (prev_euid, nobody_uid, nobody_uid) < 0)
379 {
380 printf ("setresuid failed: %m\n");
381 exit (1);
382 }
383
384 if (action != CHECK_BEFORE)
385 {
386 uid_t ruid, euid, suid;
387 if (getresuid (&ruid, &euid, &suid) < 0)
388 {
389 printf ("getresuid failed: %d %m\n", tno);
390 exit (1);
391 }
392
393 if (ruid != prev_euid || euid != nobody_uid || suid != nobody_uid)
394 {
395 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
396 ruid, euid, suid, prev_euid, nobody_uid, nobody_uid);
397 exit (1);
398 }
399 }
400}
401
402
403static void
404test_setresuid3 (enum ACTION action, int tno)
405{
406 if (action == PREPARE)
407 return;
408
409 if (action != CHECK_AFTER)
410 check_prev_uid (tno);
411
412 if (action == SET && setresuid (nobody_uid, nobody_uid, nobody_uid) < 0)
413 {
414 printf ("setresuid failed: %m\n");
415 exit (1);
416 }
417
418 if (action != CHECK_BEFORE)
419 {
420 uid_t ruid, euid, suid;
421 if (getresuid (&ruid, &euid, &suid) < 0)
422 {
423 printf ("getresuid failed: %d %m\n", tno);
424 exit (1);
425 }
426
427 if (ruid != nobody_uid || euid != nobody_uid || suid != nobody_uid)
428 {
429 printf ("after setresuid %d (%d %d %d) != (%d %d %d)\n", tno,
430 ruid, euid, suid, nobody_uid, nobody_uid, nobody_uid);
431 exit (1);
432 }
433 }
434}
435
436
437static void
438test_setresuid4 (enum ACTION action, int tno)
439{
440 if (action == PREPARE)
441 {
442 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
443 {
444 printf ("setresuid failed: %m\n");
445 exit (1);
446 }
447
448 prev_ruid = nobody_uid;
449 prev_euid = nobody_uid;
450 nobody_uid = prev_suid;
451 return;
452 }
453
454 test_setresuid1 (action, tno);
455}
456
457
458static void
459test_setgid1 (enum ACTION action, int tno)
460{
461 if (action == PREPARE)
462 return;
463
464 if (action != CHECK_AFTER)
465 check_prev_gid (tno);
466
467 if (action == SET && setgid (nobody_gid) < 0)
468 {
469 printf ("setgid failed: %m\n");
470 exit (1);
471 }
472
473 if (action != CHECK_BEFORE)
474 {
475 gid_t rgid, egid, sgid;
476 if (getresgid (&rgid, &egid, &sgid) < 0)
477 {
478 printf ("getresgid failed: %d %m\n", tno);
479 exit (1);
480 }
481
482 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
483 {
484 printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
485 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
486 exit (1);
487 }
488 }
489}
490
491
492static void
493test_setgid2 (enum ACTION action, int tno)
494{
495 if (action == PREPARE)
496 {
497 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
498 {
499 printf ("setresgid failed: %m\n");
500 exit (1);
501 }
502
503 prev_rgid = nobody_gid;
504 prev_egid = nobody_gid;
505
506 if (setresuid (nobody_uid, nobody_uid, -1) < 0)
507 {
508 printf ("setresuid failed: %m\n");
509 exit (1);
510 }
511
512 prev_ruid = nobody_uid;
513 prev_euid = nobody_uid;
514 return;
515 }
516
517 if (action != CHECK_AFTER)
518 check_prev_gid (tno);
519
520 if (action == SET && setgid (prev_sgid) < 0)
521 {
522 printf ("setgid failed: %m\n");
523 exit (1);
524 }
525
526 if (action != CHECK_BEFORE)
527 {
528 gid_t rgid, egid, sgid;
529 if (getresgid (&rgid, &egid, &sgid) < 0)
530 {
531 printf ("getresgid failed: %d %m\n", tno);
532 exit (1);
533 }
534
535 if (rgid != nobody_gid || egid != prev_sgid || sgid != prev_sgid)
536 {
537 printf ("after setgid %d (%d %d %d) != (%d %d %d)\n", tno,
538 rgid, egid, sgid, nobody_gid, prev_sgid, prev_sgid);
539 exit (1);
540 }
541 }
542}
543
544
545static void
546test_setegid1 (enum ACTION action, int tno)
547{
548 if (action == PREPARE)
549 return;
550
551 if (action != CHECK_AFTER)
552 check_prev_gid (tno);
553
554 if (action == SET && setegid (nobody_gid) < 0)
555 {
556 printf ("setegid failed: %m\n");
557 exit (1);
558 }
559
560 if (action != CHECK_BEFORE)
561 {
562 gid_t rgid, egid, sgid;
563 if (getresgid (&rgid, &egid, &sgid) < 0)
564 {
565 printf ("getresgid failed: %d %m\n", tno);
566 exit (1);
567 }
568
569 if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
570 {
571 printf ("after setegid %d (%d %d %d) != (%d %d %d)\n", tno,
572 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
573 exit (1);
574 }
575 }
576}
577
578
579static void
580test_setegid2 (enum ACTION action, int tno)
581{
582 if (action == PREPARE)
583 {
584 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
585 {
586 printf ("setresgid failed: %m\n");
587 exit (1);
588 }
589
590 prev_rgid = nobody_gid;
591 prev_egid = nobody_gid;
592 nobody_gid = prev_sgid;
593 return;
594 }
595
596 test_setegid1 (action, tno);
597}
598
599
600static void
601test_setregid1 (enum ACTION action, int tno)
602{
603 if (action == PREPARE)
604 return;
605
606 if (action != CHECK_AFTER)
607 check_prev_gid (tno);
608
609 if (action == SET && setregid (-1, nobody_gid) < 0)
610 {
611 printf ("setregid failed: %m\n");
612 exit (1);
613 }
614
615 if (action != CHECK_BEFORE)
616 {
617 gid_t rgid, egid, sgid, esgid;
618 if (getresgid (&rgid, &egid, &sgid) < 0)
619 {
620 printf ("getresgid failed: %d %m\n", tno);
621 exit (1);
622 }
623
624 if (prev_rgid != nobody_gid)
625 esgid = nobody_gid;
626 else
627 esgid = prev_sgid;
628
629 if (rgid != prev_rgid || egid != nobody_gid || sgid != esgid)
630 {
631 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
632 rgid, egid, sgid, prev_rgid, nobody_gid, esgid);
633 exit (1);
634 }
635 }
636}
637
638
639static void
640test_setregid2 (enum ACTION action, int tno)
641{
642 if (action == PREPARE)
643 return;
644
645 if (action != CHECK_AFTER)
646 check_prev_gid (tno);
647
648 if (action == SET && setregid (nobody_gid, -1) < 0)
649 {
650 printf ("setregid failed: %m\n");
651 exit (1);
652 }
653
654 if (action != CHECK_BEFORE)
655 {
656 gid_t rgid, egid, sgid;
657 if (getresgid (&rgid, &egid, &sgid) < 0)
658 {
659 printf ("getresgid failed: %d %m\n", tno);
660 exit (1);
661 }
662
663 if (rgid != nobody_gid || egid != prev_egid || sgid != prev_egid)
664 {
665 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
666 rgid, egid, sgid, nobody_gid, prev_egid, prev_egid);
667 exit (1);
668 }
669 }
670}
671
672
673static void
674test_setregid3 (enum ACTION action, int tno)
675{
676 if (action == PREPARE)
677 return;
678
679 if (action != CHECK_AFTER)
680 check_prev_gid (tno);
681
682 if (action == SET && setregid (nobody_gid, nobody_gid) < 0)
683 {
684 printf ("setregid failed: %m\n");
685 exit (1);
686 }
687
688 if (action != CHECK_BEFORE)
689 {
690 gid_t rgid, egid, sgid;
691 if (getresgid (&rgid, &egid, &sgid) < 0)
692 {
693 printf ("getresgid failed: %d %m\n", tno);
694 exit (1);
695 }
696
697 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
698 {
699 printf ("after setregid %d (%d %d %d) != (%d %d %d)\n", tno,
700 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
701 exit (1);
702 }
703 }
704}
705
706
707static void
708test_setregid4 (enum ACTION action, int tno)
709{
710 if (action == PREPARE)
711 {
712 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
713 {
714 printf ("setresgid failed: %m\n");
715 exit (1);
716 }
717
718 prev_rgid = nobody_gid;
719 prev_egid = nobody_gid;
720 nobody_gid = prev_sgid;
721 return;
722 }
723
724 test_setregid1 (action, tno);
725}
726
727
728static void
729test_setresgid1 (enum ACTION action, int tno)
730{
731 if (action == PREPARE)
732 return;
733
734 if (action != CHECK_AFTER)
735 check_prev_gid (tno);
736
737 if (action == SET && setresgid (-1, nobody_gid, -1) < 0)
738 {
739 printf ("setresgid failed: %m\n");
740 exit (1);
741 }
742
743 if (action != CHECK_BEFORE)
744 {
745 gid_t rgid, egid, sgid;
746 if (getresgid (&rgid, &egid, &sgid) < 0)
747 {
748 printf ("getresgid failed: %d %m\n", tno);
749 exit (1);
750 }
751
752 if (rgid != prev_rgid || egid != nobody_gid || sgid != prev_sgid)
753 {
754 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
755 rgid, egid, sgid, prev_rgid, nobody_gid, prev_sgid);
756 exit (1);
757 }
758 }
759}
760
761
762static void
763test_setresgid2 (enum ACTION action, int tno)
764{
765 if (action == PREPARE)
766 return;
767
768 if (action != CHECK_AFTER)
769 check_prev_gid (tno);
770
771 if (action == SET && setresgid (prev_egid, nobody_gid, nobody_gid) < 0)
772 {
773 printf ("setresgid failed: %m\n");
774 exit (1);
775 }
776
777 if (action != CHECK_BEFORE)
778 {
779 gid_t rgid, egid, sgid;
780 if (getresgid (&rgid, &egid, &sgid) < 0)
781 {
782 printf ("getresgid failed: %d %m\n", tno);
783 exit (1);
784 }
785
786 if (rgid != prev_egid || egid != nobody_gid || sgid != nobody_gid)
787 {
788 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
789 rgid, egid, sgid, prev_egid, nobody_gid, nobody_gid);
790 exit (1);
791 }
792 }
793}
794
795
796static void
797test_setresgid3 (enum ACTION action, int tno)
798{
799 if (action == PREPARE)
800 return;
801
802 if (action != CHECK_AFTER)
803 check_prev_gid (tno);
804
805 if (action == SET && setresgid (nobody_gid, nobody_gid, nobody_gid) < 0)
806 {
807 printf ("setresgid failed: %m\n");
808 exit (1);
809 }
810
811 if (action != CHECK_BEFORE)
812 {
813 gid_t rgid, egid, sgid;
814 if (getresgid (&rgid, &egid, &sgid) < 0)
815 {
816 printf ("getresgid failed: %d %m\n", tno);
817 exit (1);
818 }
819
820 if (rgid != nobody_gid || egid != nobody_gid || sgid != nobody_gid)
821 {
822 printf ("after setresgid %d (%d %d %d) != (%d %d %d)\n", tno,
823 rgid, egid, sgid, nobody_gid, nobody_gid, nobody_gid);
824 exit (1);
825 }
826 }
827}
828
829
830static void
831test_setresgid4 (enum ACTION action, int tno)
832{
833 if (action == PREPARE)
834 {
835 if (setresgid (nobody_gid, nobody_gid, -1) < 0)
836 {
837 printf ("setresgid failed: %m\n");
838 exit (1);
839 }
840
841 prev_rgid = nobody_gid;
842 prev_egid = nobody_gid;
843 nobody_gid = prev_sgid;
844 return;
845 }
846
847 test_setresgid1 (action, tno);
848}
849
850
851static struct setuid_test
852{
853 const char *name;
854 void (*test) (enum ACTION, int tno);
855} setuid_tests[] =
856{
857 { "setuid1", test_setuid1 },
858 { "setuid2", test_setuid2 },
859 { "seteuid1", test_seteuid1 },
860 { "seteuid2", test_seteuid2 },
861 { "setreuid1", test_setreuid1 },
862 { "setreuid2", test_setreuid2 },
863 { "setreuid3", test_setreuid3 },
864 { "setreuid4", test_setreuid4 },
865 { "setresuid1", test_setresuid1 },
866 { "setresuid2", test_setresuid2 },
867 { "setresuid3", test_setresuid3 },
868 { "setresuid4", test_setresuid4 },
869 { "setgid1", test_setgid1 },
870 { "setgid2", test_setgid2 },
871 { "setegid1", test_setegid1 },
872 { "setegid2", test_setegid2 },
873 { "setregid1", test_setregid1 },
874 { "setregid2", test_setregid2 },
875 { "setregid3", test_setregid3 },
876 { "setregid4", test_setregid4 },
877 { "setresgid1", test_setresgid1 },
878 { "setresgid2", test_setresgid2 },
879 { "setresgid3", test_setresgid3 },
880 { "setresgid4", test_setresgid4 }
881};
882
883
884static void *
885tf2 (void *arg)
886{
887 int e = pthread_barrier_wait (&b4);
888 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
889 {
890 puts ("barrier_wait failed");
891 exit (1);
892 }
893
894 setuid_tests[TESTNO (arg)].test (CHECK_AFTER, THREADNO (arg));
895 return NULL;
896}
897
898
899static void *
900tf (void *arg)
901{
902 setuid_tests[TESTNO (arg)].test (CHECK_BEFORE, THREADNO (arg));
903
904 int e = pthread_barrier_wait (&b3);
905 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
906 {
907 puts ("barrier_wait failed");
908 exit (1);
909 }
910
911 return tf2 (arg);
912}
913
914
915static int
916do_one_test (long int testno)
917{
918 printf ("%s test\n", setuid_tests[testno].name);
919
920 pid_t pid = fork ();
921 if (pid == 0)
922 {
923 setuid_tests[testno].test (PREPARE, 0);
924 setuid_tests[testno].test (SET, 0);
925 exit (0);
926 }
927
928 if (pid < 0)
929 {
930 printf ("fork failed: %m\n");
931 exit (1);
932 }
933
934 int status;
935 if (waitpid (pid, &status, 0) < 0)
936 {
937 printf ("waitpid failed: %m\n");
938 exit (1);
939 }
940
941 if (!WIFEXITED (status))
942 {
943 puts ("child did not exit");
944 exit (1);
945 }
946
947 if (WEXITSTATUS (status))
948 {
949 printf ("skipping %s test\n", setuid_tests[testno].name);
950 return 0;
951 }
952
953 pid = fork ();
954 if (pid == 0)
955 {
956 setuid_tests[testno].test (PREPARE, 0);
957
958 pthread_t th;
959 int e = pthread_create (&th, NULL, tf, (void *) (testno | 0x100L));
960 if (e != 0)
961 {
962 printf ("create failed: %m\n");
963 exit (1);
964 }
965
966 pthread_t th2;
967 e = pthread_create (&th2, NULL, tf, (void *) (testno | 0x200L));
968 if (e != 0)
969 {
970 printf ("create failed: %m\n");
971 exit (1);
972 }
973
974 e = pthread_barrier_wait (&b3);
975 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
976 {
977 puts ("barrier_wait failed");
978 exit (1);
979 }
980
981 setuid_tests[testno].test (SET, 0);
982
983 pthread_t th3;
984 e = pthread_create (&th3, NULL, tf2, (void *) (testno | 0x300L));
985 if (e != 0)
986 {
987 printf ("create failed: %m\n");
988 exit (1);
989 }
990
991 e = pthread_barrier_wait (&b4);
992 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
993 {
994 puts ("barrier_wait failed");
995 exit (1);
996 }
997
998 exit (0);
999 }
1000
1001 if (pid < 0)
1002 {
1003 printf ("fork failed: %m\n");
1004 exit (1);
1005 }
1006
1007 if (waitpid (pid, &status, 0) < 0)
1008 {
1009 printf ("waitpid failed: %m\n");
1010 exit (1);
1011 }
1012
1013 if (!WIFEXITED (status))
1014 {
1015 puts ("second child did not exit");
1016 exit (1);
1017 }
1018
1019 if (WEXITSTATUS (status))
1020 exit (WEXITSTATUS (status));
1021
1022 return 0;
1023}
1024
1025
1026static int
1027do_test (void)
1028{
1029 struct passwd *pwd = getpwnam ("nobody");
1030 if (pwd == NULL)
1031 {
1032 puts ("User nobody doesn't exist");
1033 return 0;
1034 }
1035 nobody_uid = pwd->pw_uid;
1036 nobody_gid = pwd->pw_gid;
1037
1038 if (getresuid (&prev_ruid, &prev_euid, &prev_suid) < 0)
1039 {
1040 printf ("getresuid failed: %m\n");
1041 exit (1);
1042 }
1043
1044 if (getresgid (&prev_rgid, &prev_egid, &prev_sgid) < 0)
1045 {
1046 printf ("getresgid failed: %m\n");
1047 exit (1);
1048 }
1049
1050 if (prev_ruid == nobody_uid || prev_euid == nobody_uid
1051 || prev_suid == nobody_uid)
1052 {
1053 puts ("already running as user nobody, skipping tests");
1054 exit (0);
1055 }
1056
1057 if (prev_rgid == nobody_gid || prev_egid == nobody_gid
1058 || prev_sgid == nobody_gid)
1059 {
1060 puts ("already running as group nobody, skipping tests");
1061 exit (0);
1062 }
1063
1064 if (pthread_barrier_init (&b3, NULL, 3) != 0)
1065 {
1066 puts ("barrier_init failed");
1067 exit (1);
1068 }
1069
1070 if (pthread_barrier_init (&b4, NULL, 4) != 0)
1071 {
1072 puts ("barrier_init failed");
1073 exit (1);
1074 }
1075
1076 for (unsigned long int testno = 0;
1077 testno < sizeof (setuid_tests) / sizeof (setuid_tests[0]);
1078 ++testno)
1079 do_one_test (testno);
1080 return 0;
1081}
1082
1083#define TEST_FUNCTION do_test ()
1084#include "../test-skeleton.c"
1085

Warning: That file was not part of the compilation database. It may have many parsing errors.