diff options
Diffstat (limited to 'REORG.TODO/nptl/tst-setuid2.c')
-rw-r--r-- | REORG.TODO/nptl/tst-setuid2.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/REORG.TODO/nptl/tst-setuid2.c b/REORG.TODO/nptl/tst-setuid2.c new file mode 100644 index 0000000000..79cfbf4d60 --- /dev/null +++ b/REORG.TODO/nptl/tst-setuid2.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2014-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <signal.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/syscall.h> +#include <unistd.h> + +/* Check that a partial setuid failure aborts the process. */ + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cond_send; +static void (*func_sent) (void); +static pthread_cond_t cond_recv; + +#define FAIL(fmt, ...) \ + do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0) + +static void * +thread_func (void *ctx __attribute__ ((unused))) +{ + int ret = pthread_mutex_lock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_lock (thread): %d", ret); + + while (true) + { + if (func_sent != NULL) + { + void (*func) (void) = func_sent; + ret = pthread_mutex_unlock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_unlock (thread): %d", ret); + func (); + ret = pthread_mutex_lock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_lock (thread): %d", ret); + func_sent = NULL; + ret = pthread_cond_signal (&cond_recv); + if (ret != 0) + FAIL ("pthread_cond_signal (recv): %d", ret); + } + ret = pthread_cond_wait (&cond_send, &mutex); + if (ret != 0) + FAIL ("pthread_cond_wait (send): %d", ret); + } + return NULL; +} + +static void +run_on_thread (void (*func) (void)) +{ + int ret = pthread_mutex_lock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_lock (%s): %d", __func__, ret); + func_sent = func; + ret = pthread_mutex_unlock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_unlock (%s): %d", __func__, ret); + + ret = pthread_cond_signal (&cond_send); + if (ret != 0) + FAIL ("pthread_mutex_lock (%s): %d", __func__, ret); + + ret = pthread_mutex_lock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_lock (%s): %d", __func__, ret); + + while (func_sent != NULL) + { + ret = pthread_cond_wait (&cond_recv, &mutex); + if (ret != 0) + FAIL ("pthread_mutex_wait (%s): %d", __func__, ret); + } + ret = pthread_mutex_unlock (&mutex); + if (ret != 0) + FAIL ("pthread_mutex_unlock (%s): %d", __func__, ret); +} + +static void +change_thread_ids (void) +{ + long ret = syscall (__NR_setresuid, 2001, 2002, 2003); + if (ret != 0) + FAIL ("setresuid (2001, 2002, 2003): %ld", ret); +} + +static uid_t ruid, euid, suid; + +static void +get_thread_ids (void) +{ + if (getresuid (&ruid, &euid, &suid) < 0) + FAIL ("getresuid: %m (%d)", errno); +} + +static void +abort_expected (int signal __attribute__ ((unused))) +{ + _exit (0); +} + +static int +do_test (void) +{ + pthread_t thread; + int ret = pthread_create (&thread, NULL, thread_func, NULL); + if (ret != 0) + FAIL ("pthread_create: %d", ret); + + run_on_thread (change_thread_ids); + + signal (SIGABRT, &abort_expected); + /* This should abort the process. */ + if (setresuid (1001, 1002, 1003) < 0) + FAIL ("setresuid: %m (%d)", errno); + signal (SIGABRT, SIG_DFL); + + /* If we get here, check that the kernel did the right thing. */ + run_on_thread (get_thread_ids); + if (ruid != 1001 || euid != 1002 || suid != 1003) + FAIL ("unexpected UIDs after setuid: %ld, %ld, %ld", + (long) ruid, (long) euid, (long) suid); + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |