1 |
/* |
2 |
* sakura_capability_test.c |
3 |
* |
4 |
* Testing program for fs/sakura_capability.c |
5 |
* |
6 |
* Copyright (C) 2005-2006 NTT DATA CORPORATION |
7 |
* |
8 |
* Version: 1.3.1 2006/12/08 |
9 |
* |
10 |
*/ |
11 |
#include "include.h" |
12 |
|
13 |
#define DROP_KEYWORD "\\\\disable" |
14 |
|
15 |
static void ShowPrompt(const char *type, const char *range, const char *command) { |
16 |
printf("%6s: Testing %12s %20s : (must fail) ", type, range, command); |
17 |
errno = 0; |
18 |
} |
19 |
|
20 |
int main(int argc, char *argv[]) { |
21 |
int child = 0; |
22 |
const char *type = "parent"; |
23 |
|
24 |
{ |
25 |
// Am I child? |
26 |
if (argc == 2 && strcmp(argv[1], "--inherit") == 0) { |
27 |
child = 1; |
28 |
type = "child"; |
29 |
} |
30 |
} |
31 |
|
32 |
{ |
33 |
// Check the existence of dropping capability interface. |
34 |
execl(DROP_KEYWORD, DROP_KEYWORD, NULL); |
35 |
if (errno != EAGAIN) { |
36 |
fprintf(stderr, "You can't run this program for this kernel.\n"); |
37 |
return 0; |
38 |
} |
39 |
} |
40 |
|
41 |
{ |
42 |
switch (fork()) { |
43 |
case 0: |
44 |
// Drop capability for chroot(), pivot_root(), mount() if I'm parent. |
45 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "chroot", "pivotroot", "mount", NULL); |
46 |
|
47 |
ShowPrompt(type, "local", "chroot"); |
48 |
if (chroot("/") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
49 |
else printf("OK: Permission denied.\n"); |
50 |
|
51 |
ShowPrompt(type, "local", "pivotroot"); |
52 |
if (pivot_root("/", "/") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
53 |
else printf("OK: Permission denied.\n"); |
54 |
fflush(stdout); |
55 |
|
56 |
ShowPrompt(type, "local", "mount"); |
57 |
if (mount("/", "/", "nonexistent", 0, NULL) == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
58 |
else printf("OK: Permission denied.\n"); |
59 |
fflush(stdout); |
60 |
_exit(0); |
61 |
} |
62 |
wait(NULL); |
63 |
} |
64 |
{ |
65 |
switch (fork()) { |
66 |
case 0: |
67 |
// Drop capability for chroot(), pivot_root(), mount() if I'm parent. |
68 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "all-chroot", "all-pivotroot", "all-mount", NULL); |
69 |
|
70 |
ShowPrompt(type, "inheritable", "chroot"); |
71 |
if (chroot("/") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
72 |
else printf("OK: Permission denied.\n"); |
73 |
|
74 |
ShowPrompt(type, "inheritable", "pivotroot"); |
75 |
if (pivot_root("/", "/") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
76 |
else printf("OK: Permission denied.\n"); |
77 |
fflush(stdout); |
78 |
|
79 |
ShowPrompt(type, "inheritable", "mount"); |
80 |
if (mount("/", "/", "nonexistent", 0, NULL) == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
81 |
else printf("OK: Permission denied.\n"); |
82 |
fflush(stdout); |
83 |
_exit(0); |
84 |
} |
85 |
wait(NULL); |
86 |
} |
87 |
|
88 |
{ |
89 |
switch (fork()) { |
90 |
case 0: |
91 |
// Drop capability for becoming euid = 0 when euid = 0 if I'm parent. |
92 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "euid0", NULL); |
93 |
ShowPrompt(type, "local", "euid0(euid=0)"); |
94 |
// Become euid != 0. |
95 |
seteuid(1); |
96 |
// Do something that involves pathname resolution. |
97 |
chdir("."); |
98 |
// Become euid = 0. |
99 |
seteuid(0); |
100 |
// This must be rejected. |
101 |
if (chdir(".") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
102 |
else printf("OK: Permission denied.\n"); |
103 |
fflush(stdout); |
104 |
_exit(0); |
105 |
} |
106 |
wait(NULL); |
107 |
} |
108 |
{ |
109 |
switch (fork()) { |
110 |
case 0: |
111 |
// Drop capability for becoming euid = 0 when euid = 0 if I'm parent. |
112 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "all-euid0", NULL); |
113 |
ShowPrompt(type, "inheritable", "euid0(euid=0)"); |
114 |
// Become euid != 0. |
115 |
seteuid(1); |
116 |
// Do something that involves pathname resolution. |
117 |
chdir("."); |
118 |
// Become euid = 0. |
119 |
seteuid(0); |
120 |
// This must be rejected. |
121 |
if (chdir(".") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
122 |
else printf("OK: Permission denied.\n"); |
123 |
fflush(stdout); |
124 |
_exit(0); |
125 |
} |
126 |
wait(NULL); |
127 |
} |
128 |
|
129 |
{ |
130 |
switch (fork()) { |
131 |
case 0: |
132 |
// Become euid != 0. |
133 |
seteuid(1); |
134 |
// Drop capability for becoming euid = 0 when euid != 0 if I'm parent. |
135 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "euid0", NULL); |
136 |
ShowPrompt(type, "local", "euid0(euid!=0)"); |
137 |
// Do something that involves pathname resolution if I'm child. |
138 |
if (child) chdir("."); |
139 |
// Become euid = 0. |
140 |
seteuid(0); |
141 |
// This must be rejected. |
142 |
if (chdir(".") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
143 |
else printf("OK: Permission denied.\n"); |
144 |
fflush(stdout); |
145 |
_exit(0); |
146 |
} |
147 |
wait(NULL); |
148 |
} |
149 |
{ |
150 |
switch (fork()) { |
151 |
case 0: |
152 |
// Become euid != 0. |
153 |
seteuid(1); |
154 |
// Drop capability for becoming euid = 0 when euid != 0 if I'm parent. |
155 |
if (!child) execl(DROP_KEYWORD, DROP_KEYWORD, "all-euid0", NULL); |
156 |
ShowPrompt(type, "inheritable", "euid0(euid!=0)"); |
157 |
// Do something that involves pathname resolution if I'm child. |
158 |
if (child) chdir("."); |
159 |
// Become euid = 0. |
160 |
seteuid(0); |
161 |
// This must be rejected. |
162 |
if (chdir(".") == 0 || errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
163 |
else printf("OK: Permission denied.\n"); |
164 |
fflush(stdout); |
165 |
_exit(0); |
166 |
} |
167 |
wait(NULL); |
168 |
} |
169 |
|
170 |
{ |
171 |
switch (fork()) { |
172 |
case 0: |
173 |
// Drop capability for execve(). |
174 |
execl(DROP_KEYWORD, DROP_KEYWORD, "execve", NULL); |
175 |
{ |
176 |
char *argv[] = { (char *) 1, NULL }, *envp[] = { (char *) 1, NULL }; |
177 |
/* Use invalid address so that execve() won't terminate this program. */ |
178 |
ShowPrompt(type, "local", "execve"); |
179 |
execve("/bin/true", argv, envp); |
180 |
if (errno != EPERM) printf("BUG: %s\n", strerror(errno)); |
181 |
else printf("OK: Permission denied.\n"); |
182 |
} |
183 |
fflush(stdout); |
184 |
_exit(0); |
185 |
} |
186 |
wait(NULL); |
187 |
} |
188 |
{ |
189 |
// Inheriting dropped capability for execve() is impossible, for |
190 |
// using execve() needs capability for execve(). |
191 |
// Therefore, "all-execve" keyword is not implemented. |
192 |
} |
193 |
|
194 |
// No more tests for child. |
195 |
if (child) return 0; |
196 |
|
197 |
{ |
198 |
switch(fork()) { |
199 |
case 0: |
200 |
// Drop capability for chroot(), pivot_root(), mount(), euid0. |
201 |
execl(DROP_KEYWORD, DROP_KEYWORD, "all-chroot", "all-pivotroot", "all-mount", "all-euid0", NULL); |
202 |
// Run myself to check dropped capability is inherited. |
203 |
execlp(argv[0], argv[0], "--inherit", NULL); |
204 |
_exit(0); |
205 |
} |
206 |
wait(NULL); |
207 |
} |
208 |
return 0; |
209 |
} |