tests: Test the threading support of the syscalls.
authorAndreas Schneider <asn@cryptomilk.org>
Mon, 11 Nov 2013 16:31:46 +0000 (17:31 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 11 Nov 2013 18:04:00 +0000 (19:04 +0100)
tests/CMakeLists.txt
tests/test_glibc_thread_support.c [new file with mode: 0644]

index 56b96984df2e6b11c61c88010e2a8e38d9e4e01a..612cfab5101aac75a2aa0fdf9332eb0e547feac6 100644 (file)
@@ -15,4 +15,14 @@ set_property(
     PROPERTY
         ENVIRONMENT ${TEST_ENVIRONMENT})
 
+if (LINUX)
+add_cmocka_test(test_glibc_thread_support test_glibc_thread_support.c ${CMOCKA_LIBRARY})
+target_link_libraries(test_glibc_thread_support ${CMAKE_THREAD_LIBS_INIT})
+set_property(
+    TEST
+        test_glibc_thread_support
+    PROPERTY
+        ENVIRONMENT ${TEST_ENVIRONMENT})
+endif(LINUX)
+
 add_executable(getuids getuids.c)
diff --git a/tests/test_glibc_thread_support.c b/tests/test_glibc_thread_support.c
new file mode 100644 (file)
index 0000000..159cf91
--- /dev/null
@@ -0,0 +1,148 @@
+#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);
+       }
+}
+
+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);
+       }
+}
+
+int main(void) {
+       int rc;
+
+       const UnitTest tests[] = {
+               unit_test(test_syscall_setreuid),
+               unit_test(test_sync_setreuid),
+       };
+
+       rc = run_tests(tests);
+
+       return rc;
+}