source: vendor/glibc-tests/2005-06-14/nptl/tst-setuid1.c

Last change on this file was 2036, checked in by bird, 20 years ago

Initial revision

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