blob: c0ef120af87dcae2ca0d1207e5d18019449818f8 [file] [log] [blame]
Dmitry V. Levin80f7db12014-12-13 21:49:01 +00001#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4#include <assert.h>
Dmitry V. Levin530bed02014-12-14 13:30:54 +00005#include <stdlib.h>
Dmitry V. Levin80f7db12014-12-13 21:49:01 +00006#include <unistd.h>
Dmitry V. Levin77e0d2d2015-03-02 02:13:03 +00007#include <fcntl.h>
Dmitry V. Levin80f7db12014-12-13 21:49:01 +00008#include <sys/syscall.h>
9
10int
11main(void)
12{
13#if defined(__NR_getuid) \
14 && defined(__NR_setuid) \
15 && defined(__NR_getresuid) \
16 && defined(__NR_setreuid) \
17 && defined(__NR_setresuid) \
Dmitry V. Levin68804b32015-03-16 18:10:21 +000018 && defined(__NR_fchown) \
Dmitry V. Levin530bed02014-12-14 13:30:54 +000019 && defined(__NR_getgroups) \
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000020 \
21 && defined(__NR_getuid32) \
22 && defined(__NR_setuid32) \
23 && defined(__NR_getresuid32) \
24 && defined(__NR_setreuid32) \
25 && defined(__NR_setresuid32) \
Dmitry V. Levin68804b32015-03-16 18:10:21 +000026 && defined(__NR_fchown32) \
Dmitry V. Levin530bed02014-12-14 13:30:54 +000027 && defined(__NR_getgroups32) \
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000028 \
29 && __NR_getuid != __NR_getuid32 \
30 && __NR_setuid != __NR_setuid32 \
31 && __NR_getresuid != __NR_getresuid32 \
32 && __NR_setreuid != __NR_setreuid32 \
33 && __NR_setresuid != __NR_setresuid32 \
Dmitry V. Levin68804b32015-03-16 18:10:21 +000034 && __NR_fchown != __NR_fchown32 \
Dmitry V. Levin530bed02014-12-14 13:30:54 +000035 && __NR_getgroups != __NR_getgroups32 \
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000036 /**/
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000037 int uid;
Dmitry V. Levin530bed02014-12-14 13:30:54 +000038 int size;
39 int *list = 0;
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000040
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000041 uid = syscall(__NR_getuid);
Dmitry V. Levin77e0d2d2015-03-02 02:13:03 +000042
43 (void) close(0);
44 if (open("/proc/sys/kernel/overflowuid", O_RDONLY) == 0) {
45 /* we trust the kernel */
46 char buf[sizeof(int)*3];
47 int n = read(0, buf, sizeof(buf) - 1);
48 if (n) {
49 buf[n] = '\0';
50 n = atoi(buf);
51 if (uid == n)
52 return 77;
53 }
54 close(0);
55 }
56
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000057 assert(syscall(__NR_setuid, uid) == 0);
58 {
59 /*
60 * uids returned by getresuid should be ignored
61 * to avoid 16bit vs 32bit issues.
62 */
63 int r, e, s;
64 assert(syscall(__NR_getresuid, &r, &e, &s) == 0);
65 }
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000066 assert(syscall(__NR_setreuid, -1, 0xffff) == 0);
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000067 assert(syscall(__NR_setresuid, uid, -1, 0xffff) == 0);
Dmitry V. Levin68804b32015-03-16 18:10:21 +000068 assert(syscall(__NR_fchown, 1, -1, 0xffff) == 0);
Dmitry V. Levin530bed02014-12-14 13:30:54 +000069 assert((size = syscall(__NR_getgroups, 0, list)) >= 0);
70 assert(list = calloc(size + 1, sizeof(*list)));
71 assert(syscall(__NR_getgroups, size, list) == size);
Dmitry V. Levin80f7db12014-12-13 21:49:01 +000072 return 0;
73#else
74 return 77;
75#endif
76}