]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/tst-setuid2.c
LoongArch: Use "$fcsr0" instead of "$r0" in _FPU_{GET,SET}CW
[thirdparty/glibc.git] / nptl / tst-setuid2.c
CommitLineData
dff8da6b 1/* Copyright (C) 2014-2024 Free Software Foundation, Inc.
13f7fe35
FW
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
13f7fe35
FW
17
18#include <errno.h>
19#include <pthread.h>
20#include <signal.h>
21#include <stdbool.h>
22#include <stdio.h>
365b3af6 23#include <support/xthread.h>
13f7fe35
FW
24#include <sys/syscall.h>
25#include <unistd.h>
26
27/* Check that a partial setuid failure aborts the process. */
28
29static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
30static pthread_cond_t cond_send;
31static void (*func_sent) (void);
32static pthread_cond_t cond_recv;
33
34#define FAIL(fmt, ...) \
35 do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)
36
37static void *
38thread_func (void *ctx __attribute__ ((unused)))
39{
365b3af6 40 xpthread_mutex_lock (&mutex);
13f7fe35
FW
41 while (true)
42 {
43 if (func_sent != NULL)
44 {
45 void (*func) (void) = func_sent;
365b3af6
YCPL
46 xpthread_mutex_unlock (&mutex);
47
13f7fe35 48 func ();
365b3af6
YCPL
49
50 xpthread_mutex_lock (&mutex);
13f7fe35 51 func_sent = NULL;
365b3af6 52 xpthread_cond_signal (&cond_recv);
13f7fe35 53 }
365b3af6 54 xpthread_cond_wait (&cond_send, &mutex);
13f7fe35
FW
55 }
56 return NULL;
57}
58
59static void
60run_on_thread (void (*func) (void))
61{
365b3af6 62 xpthread_mutex_lock (&mutex);
13f7fe35 63 func_sent = func;
365b3af6 64 xpthread_mutex_unlock (&mutex);
13f7fe35 65
365b3af6 66 xpthread_cond_signal (&cond_send);
13f7fe35 67
365b3af6 68 xpthread_mutex_lock (&mutex);
13f7fe35
FW
69 while (func_sent != NULL)
70 {
365b3af6 71 xpthread_cond_wait (&cond_recv, &mutex);
13f7fe35 72 }
365b3af6 73 xpthread_mutex_unlock (&mutex);
13f7fe35
FW
74}
75
76static void
77change_thread_ids (void)
78{
79 long ret = syscall (__NR_setresuid, 2001, 2002, 2003);
80 if (ret != 0)
81 FAIL ("setresuid (2001, 2002, 2003): %ld", ret);
82}
83
84static uid_t ruid, euid, suid;
85
86static void
87get_thread_ids (void)
88{
89 if (getresuid (&ruid, &euid, &suid) < 0)
90 FAIL ("getresuid: %m (%d)", errno);
91}
92
93static void
94abort_expected (int signal __attribute__ ((unused)))
95{
96 _exit (0);
97}
98
99static int
100do_test (void)
101{
102 pthread_t thread;
103 int ret = pthread_create (&thread, NULL, thread_func, NULL);
104 if (ret != 0)
105 FAIL ("pthread_create: %d", ret);
106
107 run_on_thread (change_thread_ids);
108
109 signal (SIGABRT, &abort_expected);
110 /* This should abort the process. */
111 if (setresuid (1001, 1002, 1003) < 0)
112 FAIL ("setresuid: %m (%d)", errno);
113 signal (SIGABRT, SIG_DFL);
114
115 /* If we get here, check that the kernel did the right thing. */
116 run_on_thread (get_thread_ids);
a7291117 117 if (ruid != 1001 || euid != 1002 || suid != 1003)
13f7fe35
FW
118 FAIL ("unexpected UIDs after setuid: %ld, %ld, %ld",
119 (long) ruid, (long) euid, (long) suid);
120 return 0;
121}
122
365b3af6 123#include <support/test-driver.c>