]> granicus.if.org Git - strace/blob - tests/setgroups.c
tests: extend TEST_NETLINK_OBJECT macro
[strace] / tests / setgroups.c
1 /*
2  * Check decoding of setgroups/setgroups32 syscalls.
3  *
4  * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2016-2017 The strace developers.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #ifdef __NR_setgroups32
32
33 # define SYSCALL_NR     __NR_setgroups32
34 # define SYSCALL_NAME   "setgroups32"
35 # define GID_TYPE       unsigned int
36
37 #else
38
39 # include "tests.h"
40 # include <asm/unistd.h>
41
42 # ifdef __NR_setgroups
43
44 #  define SYSCALL_NR    __NR_setgroups
45 #  define SYSCALL_NAME  "setgroups"
46 #  if defined __NR_setgroups32 && __NR_setgroups != __NR_setgroups32
47 #   define GID_TYPE     unsigned short
48 #  else
49 #   define GID_TYPE     unsigned int
50 #  endif
51
52 # endif
53
54 #endif
55
56 #ifdef GID_TYPE
57
58 # include <stdio.h>
59 # include <unistd.h>
60
61 void
62 printuid(GID_TYPE id)
63 {
64         if (id == (GID_TYPE) -1U)
65                 printf("-1");
66         else
67                 printf("%u", id);
68 }
69
70 int
71 main(void)
72 {
73         const char *errstr;
74
75         /* check how the first argument is decoded */
76         long rc = syscall(SYSCALL_NR, 0, 0);
77         printf("%s(0, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
78
79         rc = syscall(SYSCALL_NR, F8ILL_KULONG_MASK, 0);
80         printf("%s(0, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
81
82         rc = syscall(SYSCALL_NR, 1, 0);
83         printf("%s(1, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
84
85         rc = syscall(SYSCALL_NR, (long) 0xffffffff00000001ULL, 0);
86         printf("%s(1, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
87
88         rc = syscall(SYSCALL_NR, -1U, 0);
89         printf("%s(%d, NULL) = %s\n", SYSCALL_NAME, -1, sprintrc(rc));
90
91         rc = syscall(SYSCALL_NR, -1L, 0);
92         printf("%s(%d, NULL) = %s\n", SYSCALL_NAME, -1, sprintrc(rc));
93
94         /* check how the second argument is decoded */
95         TAIL_ALLOC_OBJECT_CONST_PTR(const GID_TYPE, g1);
96         GID_TYPE *const g2 = tail_alloc(sizeof(*g2) * 2);
97         GID_TYPE *const g3 = tail_alloc(sizeof(*g3) * 3);
98
99         rc = syscall(SYSCALL_NR, 0, g1 + 1);
100         printf("%s(0, []) = %s\n", SYSCALL_NAME, sprintrc(rc));
101
102         rc = syscall(SYSCALL_NR, 1, g1);
103         errstr = sprintrc(rc);
104         printf("%s(1, [", SYSCALL_NAME);
105         printuid(*g1);
106         printf("]) = %s\n", errstr);
107
108         rc = syscall(SYSCALL_NR, 1, g1 + 1);
109         printf("%s(1, %p) = %s\n", SYSCALL_NAME, g1 + 1, sprintrc(rc));
110
111         rc = syscall(SYSCALL_NR, 1, -1L);
112         printf("%s(1, %#lx) = %s\n", SYSCALL_NAME, -1L, sprintrc(rc));
113
114         rc = syscall(SYSCALL_NR, 2, g1);
115         errstr = sprintrc(rc);
116         printf("%s(2, [", SYSCALL_NAME);
117         printuid(*g1);
118         printf(", %p]) = %s\n", g1 + 1, errstr);
119
120         g2[0] = -2;
121         g2[1] = -3;
122         rc = syscall(SYSCALL_NR, 2, g2);
123         errstr = sprintrc(rc);
124         printf("%s(2, [", SYSCALL_NAME);
125         printuid(g2[0]);
126         printf(", ");
127         printuid(g2[1]);
128         printf("]) = %s\n", errstr);
129
130         rc = syscall(SYSCALL_NR, 3, g2);
131         errstr = sprintrc(rc);
132         printf("%s(3, [", SYSCALL_NAME);
133         printuid(g2[0]);
134         printf(", ");
135         printuid(g2[1]);
136         printf(", %p]) = %s\n", g2 + 2, errstr);
137
138         g3[0] = 0;
139         g3[1] = 1;
140         rc = syscall(SYSCALL_NR, 3, g3);
141         errstr = sprintrc(rc);
142         printf("%s(3, [", SYSCALL_NAME);
143         printuid(g3[0]);
144         printf(", ");
145         printuid(g3[1]);
146         printf(", ...]) = %s\n", errstr);
147
148         rc = syscall(SYSCALL_NR, 4, g3);
149         errstr = sprintrc(rc);
150         printf("%s(4, [", SYSCALL_NAME);
151         printuid(g3[0]);
152         printf(", ");
153         printuid(g3[1]);
154         printf(", ...]) = %s\n", errstr);
155
156         rc = sysconf(_SC_NGROUPS_MAX);
157         const unsigned ngroups_max = rc;
158
159         if ((unsigned long) rc == ngroups_max && (int) ngroups_max > 0) {
160                 rc = syscall(SYSCALL_NR, ngroups_max, g3);
161                 errstr = sprintrc(rc);
162                 printf("%s(%d, [", SYSCALL_NAME, ngroups_max);
163                 printuid(g3[0]);
164                 printf(", ");
165                 printuid(g3[1]);
166                 printf(", ...]) = %s\n", errstr);
167
168                 rc = syscall(SYSCALL_NR, F8ILL_KULONG_MASK | ngroups_max, g3);
169                 errstr = sprintrc(rc);
170                 printf("%s(%d, [", SYSCALL_NAME, ngroups_max);
171                 printuid(g3[0]);
172                 printf(", ");
173                 printuid(g3[1]);
174                 printf(", ...]) = %s\n", errstr);
175
176                 rc = syscall(SYSCALL_NR, ngroups_max + 1, g3);
177                 printf("%s(%d, %p) = %s\n", SYSCALL_NAME,
178                        ngroups_max + 1, g3, sprintrc(rc));
179         }
180
181         puts("+++ exited with 0 +++");
182         return 0;
183 }
184
185 #else
186
187 SKIP_MAIN_UNDEFINED("__NR_setgroups")
188
189 #endif