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