1 /* Copyright (C) 2014-2024 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
23 #include <support/xthread.h>
24 #include <sys/syscall.h>
27 /* Check that a partial setuid failure aborts the process. */
29 static pthread_mutex_t mutex
= PTHREAD_MUTEX_INITIALIZER
;
30 static pthread_cond_t cond_send
;
31 static void (*func_sent
) (void);
32 static pthread_cond_t cond_recv
;
34 #define FAIL(fmt, ...) \
35 do { printf ("FAIL: " fmt "\n", __VA_ARGS__); _exit (1); } while (0)
38 thread_func (void *ctx
__attribute__ ((unused
)))
40 xpthread_mutex_lock (&mutex
);
43 if (func_sent
!= NULL
)
45 void (*func
) (void) = func_sent
;
46 xpthread_mutex_unlock (&mutex
);
50 xpthread_mutex_lock (&mutex
);
52 xpthread_cond_signal (&cond_recv
);
54 xpthread_cond_wait (&cond_send
, &mutex
);
60 run_on_thread (void (*func
) (void))
62 xpthread_mutex_lock (&mutex
);
64 xpthread_mutex_unlock (&mutex
);
66 xpthread_cond_signal (&cond_send
);
68 xpthread_mutex_lock (&mutex
);
69 while (func_sent
!= NULL
)
71 xpthread_cond_wait (&cond_recv
, &mutex
);
73 xpthread_mutex_unlock (&mutex
);
77 change_thread_ids (void)
79 long ret
= syscall (__NR_setresuid
, 2001, 2002, 2003);
81 FAIL ("setresuid (2001, 2002, 2003): %ld", ret
);
84 static uid_t ruid
, euid
, suid
;
89 if (getresuid (&ruid
, &euid
, &suid
) < 0)
90 FAIL ("getresuid: %m (%d)", errno
);
94 abort_expected (int signal
__attribute__ ((unused
)))
103 int ret
= pthread_create (&thread
, NULL
, thread_func
, NULL
);
105 FAIL ("pthread_create: %d", ret
);
107 run_on_thread (change_thread_ids
);
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
);
115 /* If we get here, check that the kernel did the right thing. */
116 run_on_thread (get_thread_ids
);
117 if (ruid
!= 1001 || euid
!= 1002 || suid
!= 1003)
118 FAIL ("unexpected UIDs after setuid: %ld, %ld, %ld",
119 (long) ruid
, (long) euid
, (long) suid
);
123 #include <support/test-driver.c>