diff options
Diffstat (limited to 'sysdeps/pthread/tst-pthread-setuid-loop.c')
| -rw-r--r-- | sysdeps/pthread/tst-pthread-setuid-loop.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/sysdeps/pthread/tst-pthread-setuid-loop.c b/sysdeps/pthread/tst-pthread-setuid-loop.c new file mode 100644 index 0000000000..fda2a49b7f --- /dev/null +++ b/sysdeps/pthread/tst-pthread-setuid-loop.c @@ -0,0 +1,61 @@ +/* Test that setuid, pthread_create, thread exit do not deadlock (bug 28361). + Copyright (C) 2021 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 + <https://www.gnu.org/licenses/>. */ + +#include <support/check.h> +#include <support/xthread.h> +#include <unistd.h> + +/* How many threads to launch during each iteration. */ +enum { threads = 4 }; + +/* How many iterations to perform. This value seems to reproduce + bug 28361 in a bout one in three runs. */ +enum { iterations = 5000 }; + +/* Cache of the real user ID used by setuid_thread. */ +static uid_t uid; + +/* Start routine for the threads. */ +static void * +setuid_thread (void *closure) +{ + TEST_COMPARE (setuid (uid), 0); + return NULL; +} + +static int +do_test (void) +{ + /* The setxid machinery is still invoked even if the UID is + unchanged. (The kernel might reset other credentials as part of + the system call.) */ + uid = getuid (); + + for (int i = 0; i < iterations; ++i) + { + pthread_t thread_ids[threads]; + for (int j = 0; j < threads; ++j) + thread_ids[j] = xpthread_create (NULL, setuid_thread, NULL); + for (int j = 0; j < threads; ++j) + xpthread_join (thread_ids[j]); + } + + return 0; +} + +#include <support/test-driver.c> |
