blob: bf4d8d2288534399ba7e86636f6d59d96e2058f9 [file] [log] [blame]
Dmitry V. Levin1da7c952014-12-13 18:24:13 +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. Levin1da7c952014-12-13 18:24:13 +00006#include <unistd.h>
Dmitry V. Levin04fcb992015-07-22 19:31:54 +00007#include <fcntl.h>
Dmitry V. Levin1da7c952014-12-13 18:24:13 +00008#include <sys/syscall.h>
9
10int
11main(void)
12{
Dmitry V. Levin8ef54392015-07-16 09:09:11 +000013#if (defined __NR_getuid || defined __NR_getxuid) \
Dmitry V. Levin1da7c952014-12-13 18:24:13 +000014 && 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. Levin3a15bc82015-03-02 01:13:47 +000020 int uid;
Dmitry V. Levin530bed02014-12-14 13:30:54 +000021 int size;
22 int *list = 0;
Dmitry V. Levin1da7c952014-12-13 18:24:13 +000023
Dmitry V. Levin8ef54392015-07-16 09:09:11 +000024#ifndef __NR_getuid
25# define __NR_getuid __NR_getxuid
26#endif
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000027 uid = syscall(__NR_getuid);
Dmitry V. Levin04fcb992015-07-22 19:31:54 +000028
29 (void) close(0);
30 if (open("/proc/sys/kernel/overflowuid", O_RDONLY) == 0) {
31 /* we trust the kernel */
32 char buf[sizeof(int)*3];
33 int n = read(0, buf, sizeof(buf) - 1);
34 if (n) {
35 buf[n] = '\0';
36 n = atoi(buf);
37 if (uid == n)
38 return 77;
39 }
40 (void) close(0);
41 }
42
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000043 assert(syscall(__NR_setuid, uid) == 0);
44 {
45 /*
46 * uids returned by getresuid should be ignored
47 * to avoid 16bit vs 32bit issues.
48 */
49 int r, e, s;
50 assert(syscall(__NR_getresuid, &r, &e, &s) == 0);
51 }
Dmitry V. Levin1da7c952014-12-13 18:24:13 +000052 assert(syscall(__NR_setreuid, -1, -1L) == 0);
Dmitry V. Levin3a15bc82015-03-02 01:13:47 +000053 assert(syscall(__NR_setresuid, uid, -1, -1L) == 0);
Dmitry V. Levin68804b32015-03-16 18:10:21 +000054 assert(syscall(__NR_fchown, 1, -1, -1L) == 0);
Dmitry V. Levin530bed02014-12-14 13:30:54 +000055 assert((size = syscall(__NR_getgroups, 0, list)) >= 0);
56 assert(list = calloc(size + 1, sizeof(*list)));
57 assert(syscall(__NR_getgroups, size, list) == size);
Dmitry V. Levin1da7c952014-12-13 18:24:13 +000058 return 0;
59#else
60 return 77;
61#endif
62}