Require autoconf 2.69
[glibc.git] / nptl / tst-setuid3.c
blobf78f48523917663a577f7648679dbc0aa86b1ee7
1 /* Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. */
18 #include <err.h>
19 #include <errno.h>
20 #include <pthread.h>
21 #include <stdbool.h>
22 #include <unistd.h>
24 /* The test must run under a non-privileged user ID. */
25 static const uid_t test_uid = 1;
27 static pthread_barrier_t barrier1;
28 static pthread_barrier_t barrier2;
30 static void *
31 thread_func (void *ctx __attribute__ ((unused)))
33 int ret = pthread_barrier_wait (&barrier1);
34 if (ret != PTHREAD_BARRIER_SERIAL_THREAD && ret != 0)
35 errx (1, "pthread_barrier_wait (barrier1) (on thread): %d", ret);
36 ret = pthread_barrier_wait (&barrier2);
37 if (ret != PTHREAD_BARRIER_SERIAL_THREAD && ret != 0)
38 errx (1, "pthread_barrier_wait (barrier2) (on thread): %d", ret);
39 return NULL;
42 static void
43 setuid_failure (int phase)
45 int ret = setuid (0);
46 switch (ret)
48 case 0:
49 errx (1, "setuid succeeded unexpectedly in phase %d", phase);
50 case -1:
51 if (errno != EPERM)
52 err (1, "setuid phase %d", phase);
53 break;
54 default:
55 errx (1, "invalid setuid return value in phase %d: %d", phase, ret);
59 static int
60 do_test (void)
62 if (getuid () == 0)
63 if (setuid (test_uid) != 0)
64 err (1, "setuid (%u)", (unsigned) test_uid);
65 if (setuid (getuid ()))
66 err (1, "setuid (getuid ())");
67 setuid_failure (1);
69 int ret = pthread_barrier_init (&barrier1, NULL, 2);
70 if (ret != 0)
71 errx (1, "pthread_barrier_init (barrier1): %d", ret);
72 ret = pthread_barrier_init (&barrier2, NULL, 2);
73 if (ret != 0)
74 errx (1, "pthread_barrier_init (barrier2): %d", ret);
76 pthread_t thread;
77 ret = pthread_create (&thread, NULL, thread_func, NULL);
78 if (ret != 0)
79 errx (1, "pthread_create: %d", ret);
81 /* Ensure that the thread is running properly. */
82 ret = pthread_barrier_wait (&barrier1);
83 if (ret != 0)
84 errx (1, "pthread_barrier_wait (barrier1): %d", ret);
86 setuid_failure (2);
88 /* Check success case. */
89 if (setuid (getuid ()) != 0)
90 err (1, "setuid (getuid ())");
92 /* Shutdown. */
93 ret = pthread_barrier_wait (&barrier2);
94 if (ret != PTHREAD_BARRIER_SERIAL_THREAD && ret != 0)
95 errx (1, "pthread_barrier_wait (barrier2): %d", ret);
97 if (ret != PTHREAD_BARRIER_SERIAL_THREAD && ret != 0)
98 errx (1, "pthread_join: %d", ret);
100 return 0;
103 #define TEST_FUNCTION do_test ()
104 #include "../test-skeleton.c"