1 /*
2 * Check decoding of setuid/setgid/setuid32/setgid32 syscalls.
3 *
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include <errno.h>
12 #include <stdio.h>
13 #include <unistd.h>
14
15 static void
16 printuid(unsigned UGID_TYPE id)
17 {
18 if (id == (unsigned UGID_TYPE) -1U)
19 printf("-1");
20 else
21 printf("%u", id);
22 }
23
24 int
25 main(void)
26 {
27 unsigned int ugid = GETUGID;
28 CHECK_OVERFLOWUGID(ugid);
29
30 const long tests[] = {
31 ugid,
32 0xffff0000U | ugid,
33 (unsigned long) 0xffffffff00000000ULL | ugid,
34 0xffffU,
35 -1U,
36 -1L
37 };
38
39 for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i) {
40 const unsigned int num = (unsigned UGID_TYPE) tests[i];
41 long expected;
42
43 errno = 0;
44
45 if (num == ugid)
46 expected = 0;
47 else if ((UGID_TYPE) num == (UGID_TYPE) -1U)
48 expected = -1;
49 else
50 continue;
51
52 const long rc = syscall(SYSCALL_NR, tests[i]);
53 const char *errstr = sprintrc(rc);
54
55 if (rc != expected) {
56 if (!i && ENOSYS == errno) {
57 printf("%s(%u) = %s\n",
58 SYSCALL_NAME, ugid, errstr);
59 break;
60 }
61 perror_msg_and_fail("%s(%#lx) = %ld != %ld",
62 SYSCALL_NAME, tests[i],
63 rc, expected);
64 }
65
66 printf("%s(", SYSCALL_NAME);
67 printuid(num);
68 printf(") = %s\n", errstr);
69 }
70
71 puts("+++ exited with 0 +++");
72 return 0;
73 }