uwrap: Always enable logging
[uid_wrapper.git] / tests / test_glibc_thread_support.c
1 #include "config.h"
2
3 #include <stdarg.h>
4 #include <stddef.h>
5 #include <setjmp.h>
6 #include <cmocka.h>
7
8 #include <pthread.h>
9
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 #include <grp.h>
15
16 #ifdef HAVE_SYS_SYSCALL_H
17 #include <sys/syscall.h>
18 #endif
19 #ifdef HAVE_SYSCALL_H
20 #include <syscall.h>
21 #endif
22
23 #define NUM_THREADS 10
24
25 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
26
27 static void *uwrap_setgid_syscall(void *arg)
28 {
29         int rc;
30         gid_t g;
31         (void) arg; /* unused */
32
33         rc = syscall(SYS_setgid, 999);
34         assert_int_equal(rc, 0);
35
36         g = getgid();
37         assert_int_equal(g, 999);
38
39         return NULL;
40 }
41
42 static void test_sync_setgid_syscall(void **state)
43 {
44         pthread_attr_t pthread_custom_attr;
45         pthread_t threads[NUM_THREADS];
46         gid_t go, gn;
47         int i;
48
49         (void) state; /* unused */
50
51         pthread_attr_init(&pthread_custom_attr);
52
53         go = getgid();
54
55         for (i = 0; i < NUM_THREADS; i++) {
56                 pthread_create(&threads[i],
57                                &pthread_custom_attr,
58                                uwrap_setgid_syscall,
59                                NULL);
60         }
61
62         /* wait for threaads */
63         for (i = 0; i < NUM_THREADS; i++) {
64                 pthread_join(threads[i], NULL);
65         }
66
67         gn = getgid();
68         assert_int_equal(gn, go);
69
70         pthread_attr_destroy(&pthread_custom_attr);
71 }
72
73 static void *uwrap_setgid(void *arg)
74 {
75         int rc;
76         (void) arg; /* unused */
77
78         rc = setgid(999);
79         assert_int_equal(rc, 0);
80
81         return NULL;
82 }
83
84 static void *uwrap_getgid(void *arg)
85 {
86         gid_t g;
87         (void) arg; /* unused */
88
89         g = getgid();
90         assert_int_equal(g, 1999);
91
92         return NULL;
93 }
94
95 static void test_sync_setgid(void **state)
96 {
97         pthread_attr_t pthread_custom_attr;
98         pthread_t threads[NUM_THREADS];
99         gid_t g;
100         int i;
101         int rc;
102
103         (void) state; /* unused */
104
105         pthread_attr_init(&pthread_custom_attr);
106
107         for (i = 0; i < NUM_THREADS; i++) {
108                 pthread_create(&threads[i],
109                                &pthread_custom_attr,
110                                uwrap_setgid,
111                                NULL);
112         }
113
114         /* wait for threaads */
115         for (i = 0; i < NUM_THREADS; i++) {
116                 pthread_join(threads[i], NULL);
117         }
118
119         g = getgid();
120         assert_int_equal(g, 999);
121
122         rc = setgid(1999);
123         assert_int_equal(rc, 0);
124
125         pthread_create(&threads[0],
126                        &pthread_custom_attr,
127                        uwrap_getgid,
128                        NULL);
129
130         pthread_join(threads[0], NULL);
131
132         g = getgid();
133         assert_int_equal(g, 1999);
134
135         pthread_attr_destroy(&pthread_custom_attr);
136 }
137
138
139 static void *uwrap_setgroups(void *arg)
140 {
141         gid_t glist[] = { 100, 200, 300, 400, 500 };
142         int rc;
143
144         (void) arg; /* unused */
145
146         rc = setgroups(ARRAY_SIZE(glist), glist);
147         assert_int_equal(rc, 0);
148
149         return NULL;
150 }
151
152 static void *uwrap_getgroups(void *arg)
153 {
154         gid_t glist[] = { 100, 200, 300, 400, 500 };
155         gid_t rlist[16];
156         int rc;
157
158         (void) arg; /* unused */
159
160         rc = getgroups(ARRAY_SIZE(rlist), rlist);
161         assert_int_equal(rc, 5);
162
163         assert_memory_equal(glist, rlist, sizeof(glist));
164
165         return NULL;
166 }
167
168 static void test_sync_setgroups(void **state)
169 {
170         gid_t glist[] = { 100, 200, 300, 400, 500 };
171         pthread_t threads[NUM_THREADS];
172         gid_t rlist[16];
173         int rc;
174         int i;
175
176         (void) state; /* unused */
177
178         for (i = 0; i < NUM_THREADS; i++) {
179                 pthread_create(&threads[i],
180                                NULL,
181                                uwrap_setgroups,
182                                NULL);
183         }
184
185         /* wait for threaads */
186         for (i = 0; i < NUM_THREADS; i++) {
187                 pthread_join(threads[i], NULL);
188         }
189
190         rc = getgroups(ARRAY_SIZE(rlist), rlist);
191         assert_int_equal(rc, 5);
192
193         assert_memory_equal(glist, rlist, sizeof(glist));
194
195         pthread_create(&threads[0],
196                        NULL,
197                        uwrap_getgroups,
198                        NULL);
199
200         pthread_join(threads[0], NULL);
201
202 }
203
204 static void *uwrap_create_thread_setgid(void *arg)
205 {
206         pthread_t thread;
207         signed int tmp;
208         gid_t g, g_a;
209         int rc;
210
211         tmp = *((signed int *) arg);
212
213         if (tmp >= 0) {
214                 g_a = (gid_t) *((unsigned int *) arg);
215
216                 rc = syscall(SYS_setgid, g_a);
217                 assert_int_equal(rc, 0);
218
219                 g = getgid();
220                 assert_int_equal(g, g_a);
221
222                 tmp *= -1;
223                 rc = pthread_create(&thread,
224                                 NULL,
225                                 &uwrap_create_thread_setgid,
226                                 (void *) &tmp);
227                 assert_int_equal(rc, 0);
228
229                 pthread_join(thread, NULL);
230
231                 g = getgid();
232                 assert_int_equal(g, g_a);
233         } else {
234                 tmp *= -1;
235                 g_a = (gid_t) tmp;
236                 g = getgid();
237                 assert_int_equal(g, g_a);
238         }
239
240         pthread_exit(NULL);
241 }
242
243 static void test_thread_create_thread_setgid(void **state)
244 {
245         pthread_t thread;
246         signed int tmp = 666;
247         gid_t g;
248         int rc;
249
250         (void) state; /* unused */
251
252         rc = setgid(555);
253         assert_int_equal(rc, 0);
254         g = getgid();
255         assert_int_equal(g, 555);
256
257         pthread_create(&thread,
258                         NULL,
259                         &uwrap_create_thread_setgid,
260                         &tmp);
261         pthread_join(thread, NULL);
262 }
263
264 int main(void) {
265         int rc;
266
267         const struct CMUnitTest thread_tests[] = {
268                 cmocka_unit_test(test_sync_setgid),
269                 cmocka_unit_test(test_sync_setgid_syscall),
270                 cmocka_unit_test(test_sync_setgroups),
271                 cmocka_unit_test(test_thread_create_thread_setgid),
272         };
273
274         rc = cmocka_run_group_tests(thread_tests, NULL, NULL);
275
276         return rc;
277 }