xref: /minix3/minix/tests/test60.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1 #include <sys/types.h>
2 #include <sys/wait.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 
6 int max_error = 5;
7 #include "common.h"
8 
9 
10 int subtest = -1;
11 
12 void test_self(void);
13 void test_setnone(void);
14 void test_setuid(void);
15 void test_setgid(void);
16 void test_effugid(void);
17 int execute(const char *prog, const char *arg);
18 
execute(const char * prog,const char * arg)19 int execute(const char *prog, const char *arg)
20 {
21   pid_t childpid;
22   int status;
23   char cmd[30];
24 
25   snprintf(cmd, sizeof(cmd), "./%s", prog);
26 
27   childpid = fork();
28   if (childpid == (pid_t) -1) {
29 	return(-2);
30   } else if (childpid == 0) {
31 	if (execl(cmd, prog, arg, NULL) == -1) {
32 		exit(-2);
33 	}
34 	return(-2);	/* Never reached */
35   } else {
36 	wait(&status);
37   }
38 
39   return(WEXITSTATUS(status));
40 }
41 
test_setgid(void)42 void test_setgid(void)
43 {
44 /* Execve a new process that has setgid bits set */
45   subtest = 3;
46 
47   /* When we exec a new process which has setgid set, that process should
48    * be tainted.
49    */
50   system("chmod 2755 setgid");
51   if (execute("setgid", "0000") != 1) e(2);
52 
53   /* When we exec a new process which has setgid set, but unsets that bit
54    * before calling issetugid() should still be tainted
55    */
56   system("chmod 2755 setgid");
57   if (execute("setgid", "0755") != 1) e(3);
58 
59   /* When we exec a new process which has setgid set, and then also sets
60    * setuid before calling issetugid() should still be tainted
61    */
62   system("chmod 2755 setgid");
63   if (execute("setgid", "06755") != 1) e(4);
64 
65   /* When we exec a new process that has setgid set, and which upon
66    * execution forks, the forked child should also be tainted */
67   system("chmod 2755 setgidfork");
68   if (execute("setgidfork", "0000") != 1) e(5);
69 }
70 
test_setuid(void)71 void test_setuid(void)
72 {
73 /* Execve a new process that has setuid bits set */
74   subtest = 4;
75 
76   /* When we exec a new process which has setuid set, that process should
77    * be tainted.
78    */
79   system("chmod 4755 setuid");
80   if (execute("setuid", "0000") != 1) e(1);
81 
82   /* When we exec a new process which has setuid set, but unsets that bit
83    * before calling issetugid() should still be tainted
84    */
85   system("chmod 4755 setuid");
86   if (execute("setuid", "0755") != 1) e(2);
87 
88   /* When we exec a new process which has setuid set, and then also sets
89    * setgid before calling issetugid() should still be tainted
90    */
91   system("chmod 4755 setuid");
92   if (execute("setuid", "06755") != 1) e(3);
93 
94   /* When we exec a new process that has setgid set, and which upon
95    * execution forks, the forked child should also be tainted */
96   system("chmod 4755 setuidfork");
97   if (execute("setuidfork", "0000") != 1) e(4);
98 
99 }
100 
test_setugid(void)101 static void test_setugid(void)
102 {
103 /* Execve a new process that has setuid and setgid bits set */
104   subtest = 5;
105 
106   /* When we exec a new process which has setugid set, that
107    * process should be tainted.
108    */
109   system("chmod 6755 setugid");
110   if (execute("setugid", "0000") != 1) e(1);
111 
112   /* When we exec a new process which has setugid set, but unsets those bits
113    * before calling issetugid() should still be tainted
114    */
115   system("chmod 6755 setugid");
116   if (execute("setugid", "0755") != 1) e(2);
117 
118   /* When we exec a new process that has setugid set, and which upon
119    * execution forks, the forked child should also be tainted */
120   system("chmod 6755 setugidfork");
121   if (execute("setugidfork", "0000") != 1) e(4);
122 
123 }
124 
test_effugid(void)125 void test_effugid(void)
126 {
127 /* Test taint status with different effective uid and gid */
128   pid_t childpid;
129   int status;
130 
131   subtest = 6;
132 
133   /* Start with effective uid */
134   childpid = fork();
135   if (childpid == (pid_t) -1) e(1);
136   else if (childpid == 0) {
137 	/* We're the child */
138 
139 	/* We should be tainted */
140 	if (issetugid() != 1) e(2);
141 
142 	/* Now execute a program without set{u,g}id; should not be tainted */
143 	system("chmod 755 nobits");
144 	if (execute("nobits", "0000") != 0) e(3);
145 
146 	/* Change effective uid into current+42 and try nobits again. This time
147 	 * it should be tainted */
148 	if (seteuid(geteuid() + 42) != 0) e(4);
149 	if (execute("nobits", "0000") != 1) e(5);
150 	exit(EXIT_SUCCESS);
151   } else {
152 	/* We're the parent, wait for the child to finish */
153 	wait(&status);
154   }
155 
156   /* Now test effective gid */
157   childpid = fork();
158   if (childpid == (pid_t) -1) e(1);
159   else if (childpid == 0) {
160 	/* We're the child */
161 
162 	/* We should be tainted */
163 	if (issetugid() != 1) e(2);
164 
165 	/* Now execute a program without set{u,g}id; should not be tainted */
166 	system("chmod 755 nobits");
167 	if (execute("nobits", "0000") != 0) e(3);
168 
169 	/* Change effective gid into current+42 and try nobits again. This time
170 	 * it should be tainted */
171 	if (seteuid(getegid() + 42) != 0) e(4);
172 	if (execute("nobits", "0000") != 1) e(5);
173 	exit(EXIT_SUCCESS);
174   } else {
175 	/* We're the parent, wait for the child to finish */
176 	wait(&status);
177   }
178 }
179 
test_setnone(void)180 void test_setnone(void)
181 {
182 /* Execve a new process that does not have setuid or setgid bits set */
183   subtest = 2;
184 
185   /* When we exec a new process which doesn't have set{u,g}id set, that
186    * process should not be tainted */
187   system("chmod 755 nobits");
188   if (execute("nobits", "0000") != 0) e(2);
189 
190   /* When we exec a new process which doesn't have set{u,g}id set, but
191    * sets them after execution, the process should still not be tainted
192    */
193   system("chmod 755 nobits");
194   if (execute("nobits", "02755") != 0) e(4);
195   system("chmod 755 nobits");
196   if (execute("nobits", "04755") != 0) e(3);
197   system("chmod 755 nobits");
198   if (execute("nobits", "06755") != 0) e(5);
199 
200   /* When we exec a new process that doesn't have setugid set, and which upon
201    * execution forks, the forked child should not be tainted either */
202   system("chmod 755 nobitsfork");
203   if (execute("nobitsfork", "0000") != 0) e(6);
204 }
205 
test_self(void)206 void test_self(void)
207 {
208 /* We're supposed to be setuid. Verify. */
209 
210   int status;
211   pid_t childpid;
212 
213   subtest = 1;
214 
215   if (issetugid() != 1) e(1);
216   childpid = fork();
217   if (childpid == -1) e(2);
218   else if (childpid == 0) {
219 	/* We're the child and should inherit the tainted status of the parent
220 	 */
221 	if (issetugid() != 1) e(3);
222 
223 	/* Let's change to the bin user */
224 	if (setuid((uid_t) 2) != 0) e(4);
225 	if (getuid() != (uid_t) 2) e(5);
226 
227 	/* At this point, taint status should not have changed. */
228 	if (issetugid() != 1) e(6);
229 
230 	exit(EXIT_SUCCESS);
231   } else {
232 	/* We're the parent. Wait for the child to finish */
233 	wait(&status);
234   }
235 }
236 
switch_to_su(void)237 static void switch_to_su(void)
238 {
239   subtest = 0;
240   if (setuid(0) != 0) e(1);
241 }
242 
main(int argc,char ** argv)243 int main(int argc, char **argv)
244 {
245   start(60);
246   system("cp ../t60a nobits");
247   system("cp ../t60a setgid");
248   system("cp ../t60a setuid");
249   system("cp ../t60a setugid");
250   system("cp ../t60b nobitsfork");
251   system("cp ../t60b setuidfork");
252   system("cp ../t60b setgidfork");
253   system("cp ../t60b setugidfork");
254 
255   switch_to_su();	/* We have to be root to perform this test */
256   test_self();
257   test_setnone();
258   test_setuid();
259   test_setgid();
260   test_setugid();
261   test_effugid();
262 
263   quit();
264 
265   return(-1);	/* Never reached */
266 }
267