1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include "config.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
#ifdef HAVE_SYSCALL_H
#include <syscall.h>
#endif
#define NUM_THREADS 3
struct parm {
int id;
int ready;
};
pthread_mutex_t msg_mutex = PTHREAD_MUTEX_INITIALIZER;
static void *syscall_setreuid(void *arg)
{
long int rc;
uid_t u;
(void) arg; /* unused */
rc = syscall(SYS_setreuid, -1, 0);
assert_int_equal(rc, 0);
u = geteuid();
assert_int_equal(u, 0);
return NULL;
}
static void test_syscall_setreuid(void **state)
{
pthread_attr_t pthread_custom_attr;
pthread_t *threads;
int i;
(void) state; /* unused */
threads = (pthread_t*)malloc(NUM_THREADS * sizeof(pthread_t));
assert_non_null(threads);
pthread_attr_init(&pthread_custom_attr);
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i],
&pthread_custom_attr,
syscall_setreuid,
NULL);
}
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
free(threads);
}
static void *sync_setreuid(void *arg)
{
struct parm *p = (struct parm *)arg;
uid_t u;
syscall_setreuid(arg);
p->ready = 1;
pthread_mutex_lock(&msg_mutex);
u = geteuid();
assert_int_equal(u, 42);
pthread_mutex_unlock(&msg_mutex);
return NULL;
}
static void test_sync_setreuid(void **state)
{
pthread_attr_t pthread_custom_attr;
pthread_t *threads;
struct parm *p;
int rc;
int i;
(void) state; /* unused */
threads = (pthread_t*)malloc(NUM_THREADS * sizeof(pthread_t));
assert_non_null(threads);
pthread_attr_init(&pthread_custom_attr);
p = malloc(NUM_THREADS * sizeof(struct parm));
assert_non_null(p);
pthread_mutex_lock(&msg_mutex);
for (i = 0; i < NUM_THREADS; i++) {
p[i].id = i;
p[i].ready = 0;
pthread_create(&threads[i],
&pthread_custom_attr,
sync_setreuid,
(void *)&p[i]);
}
/* wait for the reads to set euid to 0 */
for (i = 0; i < NUM_THREADS; i++) {
while (p[i].ready != 1) {
sleep(1);
}
}
rc = setreuid(-1, 42);
assert_int_equal(rc, 0);
pthread_mutex_unlock(&msg_mutex);
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
free(threads);
free(p);
}
int main(void) {
int rc;
const UnitTest tests[] = {
unit_test(test_syscall_setreuid),
unit_test(test_sync_setreuid),
};
rc = run_tests(tests);
return rc;
}
|