180f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#ifdef HAVE_CONFIG_H
280f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin# include "config.h"
380f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#endif
480f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#include <assert.h>
5530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin#include <stdlib.h>
680f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#include <unistd.h>
777e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin#include <fcntl.h>
880f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#include <sys/syscall.h>
980f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin
1080f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levinint
1180f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levinmain(void)
1280f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin{
1380f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#if defined(__NR_getuid) \
1480f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setuid) \
1580f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_getresuid) \
1680f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setreuid) \
1780f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setresuid) \
1868804b326709fadc7bb03f510a11771f07216a59Dmitry V. Levin && defined(__NR_fchown) \
19530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin && defined(__NR_getgroups) \
2080f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin \
2180f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_getuid32) \
2280f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setuid32) \
2380f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_getresuid32) \
2480f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setreuid32) \
2580f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && defined(__NR_setresuid32) \
2668804b326709fadc7bb03f510a11771f07216a59Dmitry V. Levin && defined(__NR_fchown32) \
27530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin && defined(__NR_getgroups32) \
2880f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin \
2980f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && __NR_getuid != __NR_getuid32 \
3080f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && __NR_setuid != __NR_setuid32 \
3180f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && __NR_getresuid != __NR_getresuid32 \
3280f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && __NR_setreuid != __NR_setreuid32 \
3380f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin && __NR_setresuid != __NR_setresuid32 \
3468804b326709fadc7bb03f510a11771f07216a59Dmitry V. Levin && __NR_fchown != __NR_fchown32 \
35530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin && __NR_getgroups != __NR_getgroups32 \
3680f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin /**/
373a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	int uid;
38530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin	int size;
39530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin	int *list = 0;
4080f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin
413a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	uid = syscall(__NR_getuid);
4277e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin
4377e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin	(void) close(0);
4477e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin	if (open("/proc/sys/kernel/overflowuid", O_RDONLY) == 0) {
4577e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		/* we trust the kernel */
4677e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		char buf[sizeof(int)*3];
4777e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		int n = read(0, buf, sizeof(buf) - 1);
4877e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		if (n) {
4977e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin			buf[n] = '\0';
5077e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin			n = atoi(buf);
5177e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin			if (uid == n)
5277e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin				return 77;
5377e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		}
5477e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin		close(0);
5577e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin	}
5677e0d2dccc2487923325571f02cba5c377d5bb9aDmitry V. Levin
573a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	assert(syscall(__NR_setuid, uid) == 0);
583a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	{
593a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		/*
603a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		 * uids returned by getresuid should be ignored
613a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		 * to avoid 16bit vs 32bit issues.
623a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		 */
633a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		int r, e, s;
643a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin		assert(syscall(__NR_getresuid, &r, &e, &s) == 0);
653a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	}
6680f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin	assert(syscall(__NR_setreuid, -1, 0xffff) == 0);
673a15bc8adf3031b474a81e1c672c11817c8ee8f0Dmitry V. Levin	assert(syscall(__NR_setresuid, uid, -1, 0xffff) == 0);
6868804b326709fadc7bb03f510a11771f07216a59Dmitry V. Levin	assert(syscall(__NR_fchown, 1, -1, 0xffff) == 0);
69530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin	assert((size = syscall(__NR_getgroups, 0, list)) >= 0);
70530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin	assert(list = calloc(size + 1, sizeof(*list)));
71530bed0ca8285188ce6cbc9406e817da0ef4828bDmitry V. Levin	assert(syscall(__NR_getgroups, size, list) == size);
7280f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin	return 0;
7380f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#else
7480f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin	return 77;
7580f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin#endif
7680f7db1fedefedb01cd2ce3107dfc264eab50601Dmitry V. Levin}
77