]> granicus.if.org Git - strace/blob - tests/setresugid.c
177583d31bcb05ef72d2d0a22c94ac80bed1a4bc
[strace] / tests / setresugid.c
1 /*
2  * Check decoding of setresuid/setresgid/setresuid32/setresgid32 syscalls.
3  *
4  * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9
10 #include <errno.h>
11 #include <stdio.h>
12 #include <unistd.h>
13
14 static int
15 ugid2int(const unsigned UGID_TYPE ugid)
16 {
17         if ((unsigned UGID_TYPE) -1U == ugid)
18                 return -1;
19         else
20                 return ugid;
21 }
22
23 static void
24 print_int(const unsigned int num)
25 {
26         if (num == -1U)
27                 printf("-1");
28         else
29                 printf("%u", num);
30 }
31
32 static int
33 num_matches_id(const unsigned int num, const unsigned int ugid)
34 {
35         return num == ugid || num == -1U;
36 }
37
38 #define TRIPLE(val)     \
39         { val, ugid, ugid }, { ugid, val, ugid }, { ugid, ugid, val }
40
41 int
42 main(void)
43 {
44         unsigned int ugid = GETUGID;
45         CHECK_OVERFLOWUGID(ugid);
46
47         const struct {
48                 const long r, e, s;
49         } tests[] = {
50                 { ugid, ugid, ugid },
51                 TRIPLE((unsigned long) 0xffffffff00000000ULL | ugid),
52                 TRIPLE(-1U),
53                 TRIPLE(-1L),
54                 TRIPLE(0xffff0000U | ugid),
55                 TRIPLE(0xffff),
56                 TRIPLE(0xc0deffffU)
57         };
58
59         unsigned int i;
60
61         for (i = 0; i < ARRAY_SIZE(tests); ++i) {
62                 const unsigned int rn = ugid2int(tests[i].r);
63                 const unsigned int en = ugid2int(tests[i].e);
64                 const unsigned int sn = ugid2int(tests[i].s);
65
66                 if (!num_matches_id(rn, ugid) ||
67                     !num_matches_id(en, ugid) ||
68                     !num_matches_id(sn, ugid))
69                         continue;
70
71                 if (syscall(SYSCALL_NR, tests[i].r, tests[i].e, tests[i].s)) {
72                         if (!i && ENOSYS == errno) {
73                                 printf("%s(%u, %u, %u) = -1 ENOSYS (%m)\n",
74                                        SYSCALL_NAME, ugid, ugid, ugid);
75                                 break;
76                         }
77                         perror_msg_and_fail("%s(%#lx, %#lx, %#lx)",
78                                             SYSCALL_NAME,
79                                             tests[i].r, tests[i].e, tests[i].s);
80                 }
81
82                 printf("%s(", SYSCALL_NAME);
83                 print_int(rn);
84                 printf(", ");
85                 print_int(en);
86                 printf(", ");
87                 print_int(sn);
88                 printf(") = 0\n");
89         }
90
91         puts("+++ exited with 0 +++");
92         return 0;
93 }