1 /******************************************************************************/ 2 /* This program is free software; you can redistribute it and/or modify */ 3 /* it under the terms of the GNU General Public License as published by */ 4 /* the Free Software Foundation; either version 2 of the License, or */ 5 /* (at your option) any later version. */ 6 /* */ 7 /* This program is distributed in the hope that it will be useful, */ 8 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 9 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 10 /* the GNU General Public License for more details. */ 11 /* */ 12 /* You should have received a copy of the GNU General Public License */ 13 /* along with this program; if not, write to the Free Software */ 14 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 15 /* */ 16 /******************************************************************************/ 17 /* 18 * tomoyo_file_test.c 19 * 20 * Testing program for security/tomoyo/ 21 * 22 * Copyright (C) 2005-2010 NTT DATA CORPORATION 23 */ 24 #include "include.h" 25 26 static int should_fail = 0; 27 28 static void show_prompt(const char *str) 29 { 30 printf("Testing %35s: (%s) ", str, 31 should_fail ? "must fail" : "should success"); 32 errno = 0; 33 } 34 35 static void show_result(int result) 36 { 37 if (should_fail) { 38 if (result == EOF) { 39 if (errno == EPERM) 40 printf("OK: Permission denied.\n"); 41 else 42 printf("FAILED: %s\n", strerror(errno)); 43 } else { 44 printf("BUG!\n"); 45 } 46 } else { 47 if (result != EOF) 48 printf("OK\n"); 49 else 50 printf("%s\n", strerror(errno)); 51 } 52 } 53 54 static const char *dev_null_path = "/dev/null"; 55 static const char *truncate_path = "/tmp/truncate_test"; 56 static const char *ftruncate_path = "/tmp/ftruncate_test"; 57 static const char *open_creat_path = "/tmp/open_test"; 58 static const char *mknod_reg_path = "/tmp/mknod_reg_test"; 59 static const char *mknod_chr_path = "/tmp/mknod_chr_test"; 60 static const char *mknod_blk_path = "/tmp/mknod_blk_test"; 61 static const char *mknod_fifo_path = "/tmp/mknod_fifo_test"; 62 static const char *mknod_sock_path = "/tmp/mknod_sock_test"; 63 static const char *unlink_path = "/tmp/unlink_test"; 64 static const char *mkdir_path = "/tmp/mkdir_test"; 65 static const char *rmdir_path = "/tmp/rmdir_test"; 66 static const char *link_source_path = "/tmp/link_source_test"; 67 static const char *link_dest_path = "/tmp/link_dest_test"; 68 static const char *symlink_source_path = "/tmp/symlink_source_test"; 69 static const char *symlink_dest_path = "/tmp/symlink_dest_test"; 70 static const char *rename_source_path = "/tmp/rename_source_test"; 71 static const char *rename_dest_path = "/tmp/rename_dest_test"; 72 static const char *socket_path = "/tmp/socket_test"; 73 74 static int ftruncate_fd = EOF; 75 76 static void stage_file_test(void) 77 { 78 int fd; 79 { 80 const char buffer[] = "32768 61000"; 81 show_prompt("sysctl(READ)"); 82 show_result(read_sysctl(TEST_SYSCTL_PATH, NULL, 0)); 83 show_prompt("sysctl(WRITE)"); 84 show_result(write_sysctl(TEST_SYSCTL_PATH, buffer)); 85 } 86 87 /* QUESTION: Is there a file which can be passed to uselib()? */ 88 show_prompt("uselib()"); 89 show_result(uselib("/bin/true")); 90 91 { 92 int pipe_fd[2] = { EOF, EOF }; 93 int error = 0; 94 fflush(stdout); 95 fflush(stderr); 96 if (pipe(pipe_fd) == -1) 97 err(1, "pipe"); 98 if (fork() == 0) { 99 execl("/bin/true", "/bin/true", NULL); 100 if (write(pipe_fd[1], &errno, sizeof(errno)) == -1) 101 err(1, "write"); 102 _exit(0); 103 } 104 close(pipe_fd[1]); 105 (void)read(pipe_fd[0], &error, sizeof(error)); 106 show_prompt("execve()"); 107 errno = error; 108 show_result(error ? EOF : 0); 109 } 110 111 show_prompt("open(O_RDONLY)"); 112 fd = open(dev_null_path, O_RDONLY); 113 show_result(fd); 114 if (fd != EOF) 115 close(fd); 116 117 show_prompt("open(O_WRONLY)"); 118 fd = open(dev_null_path, O_WRONLY); 119 show_result(fd); 120 if (fd != EOF) 121 close(fd); 122 123 show_prompt("open(O_RDWR)"); 124 fd = open(dev_null_path, O_RDWR); 125 show_result(fd); 126 if (fd != EOF) 127 close(fd); 128 129 show_prompt("open(O_CREAT | O_EXCL)"); 130 fd = open(open_creat_path, O_CREAT | O_EXCL, 0666); 131 show_result(fd); 132 if (fd != EOF) 133 close(fd); 134 135 show_prompt("open(O_TRUNC)"); 136 fd = open(truncate_path, O_TRUNC); 137 show_result(fd); 138 if (fd != EOF) 139 close(fd); 140 141 show_prompt("truncate()"); 142 show_result(truncate(truncate_path, 0)); 143 144 show_prompt("ftruncate()"); 145 show_result(ftruncate(ftruncate_fd, 0)); 146 147 show_prompt("mknod(S_IFREG)"); 148 show_result(mknod(mknod_reg_path, S_IFREG, 0)); 149 150 show_prompt("mknod(S_IFCHR)"); 151 show_result(mknod(mknod_chr_path, S_IFCHR, MKDEV(1, 3))); 152 153 show_prompt("mknod(S_IFBLK)"); 154 show_result(mknod(mknod_blk_path, S_IFBLK, MKDEV(1, 0))); 155 156 show_prompt("mknod(S_IFIFO)"); 157 show_result(mknod(mknod_fifo_path, S_IFIFO, 0)); 158 159 show_prompt("mknod(S_IFSOCK)"); 160 show_result(mknod(mknod_sock_path, S_IFSOCK, 0)); 161 162 show_prompt("mkdir()"); 163 show_result(mkdir(mkdir_path, 0600)); 164 165 show_prompt("rmdir()"); 166 show_result(rmdir(rmdir_path)); 167 168 show_prompt("unlink()"); 169 show_result(unlink(unlink_path)); 170 171 show_prompt("symlink()"); 172 show_result(symlink(symlink_dest_path, symlink_source_path)); 173 174 show_prompt("link()"); 175 show_result(link(link_source_path, link_dest_path)); 176 177 show_prompt("rename()"); 178 show_result(rename(rename_source_path, rename_dest_path)); 179 180 { 181 struct sockaddr_un addr; 182 int fd; 183 memset(&addr, 0, sizeof(addr)); 184 addr.sun_family = AF_UNIX; 185 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); 186 fd = socket(AF_UNIX, SOCK_STREAM, 0); 187 show_prompt("unix_bind()"); 188 show_result(bind(fd, (struct sockaddr *)&addr, sizeof(addr))); 189 if (fd != EOF) 190 close(fd); 191 } 192 193 printf("\n\n"); 194 } 195 196 static void create_files(void) 197 { 198 mkdir(rmdir_path, 0700); 199 close(creat(link_source_path, 0600)); 200 close(creat(rename_source_path, 0600)); 201 close(creat(truncate_path, 0600)); 202 close(creat(unlink_path, 0600)); 203 ftruncate_fd = open(ftruncate_path, O_WRONLY | O_CREAT, 0600); 204 } 205 206 static void creanup_files(void) 207 { 208 if (ftruncate_fd != EOF) 209 close(ftruncate_fd); 210 ftruncate_fd = EOF; 211 unlink(open_creat_path); 212 unlink(mknod_reg_path); 213 unlink(mknod_chr_path); 214 unlink(mknod_blk_path); 215 unlink(mknod_fifo_path); 216 unlink(mknod_sock_path); 217 rmdir(mkdir_path); 218 unlink(symlink_source_path); 219 unlink(symlink_dest_path); 220 unlink(link_source_path); 221 unlink(link_dest_path); 222 unlink(rename_source_path); 223 unlink(rename_dest_path); 224 unlink(truncate_path); 225 unlink(ftruncate_path); 226 unlink(socket_path); 227 } 228 229 static void set_file_enforce(int enforce) 230 { 231 if (enforce) { 232 set_profile(3, "file::execute"); 233 set_profile(3, "file::open"); 234 set_profile(3, "file::create"); 235 set_profile(3, "file::unlink"); 236 set_profile(3, "file::mkdir"); 237 set_profile(3, "file::rmdir"); 238 set_profile(3, "file::mkfifo"); 239 set_profile(3, "file::mksock"); 240 set_profile(3, "file::truncate"); 241 set_profile(3, "file::symlink"); 242 set_profile(3, "file::rewrite"); 243 set_profile(3, "file::mkblock"); 244 set_profile(3, "file::mkchar"); 245 set_profile(3, "file::link"); 246 set_profile(3, "file::rename"); 247 set_profile(3, "file::chmod"); 248 set_profile(3, "file::chown"); 249 set_profile(3, "file::chgrp"); 250 set_profile(3, "file::ioctl"); 251 set_profile(3, "file::chroot"); 252 set_profile(3, "file::mount"); 253 set_profile(3, "file::umount"); 254 set_profile(3, "file::pivot_root"); 255 } else { 256 set_profile(0, "file::execute"); 257 set_profile(0, "file::open"); 258 set_profile(0, "file::create"); 259 set_profile(0, "file::unlink"); 260 set_profile(0, "file::mkdir"); 261 set_profile(0, "file::rmdir"); 262 set_profile(0, "file::mkfifo"); 263 set_profile(0, "file::mksock"); 264 set_profile(0, "file::truncate"); 265 set_profile(0, "file::symlink"); 266 set_profile(0, "file::rewrite"); 267 set_profile(0, "file::mkblock"); 268 set_profile(0, "file::mkchar"); 269 set_profile(0, "file::link"); 270 set_profile(0, "file::rename"); 271 set_profile(0, "file::chmod"); 272 set_profile(0, "file::chown"); 273 set_profile(0, "file::chgrp"); 274 set_profile(0, "file::ioctl"); 275 set_profile(0, "file::chroot"); 276 set_profile(0, "file::mount"); 277 set_profile(0, "file::umount"); 278 set_profile(0, "file::pivot_root"); 279 } 280 } 281 282 int main(int argc, char *argv[]) 283 { 284 tomoyo_test_init(); 285 286 printf("***** Testing file hooks in enforce mode. *****\n"); 287 create_files(); 288 should_fail = 1; 289 set_file_enforce(1); 290 stage_file_test(); 291 set_file_enforce(0); 292 clear_status(); 293 creanup_files(); 294 295 printf("***** Testing file hooks in permissive mode. *****\n"); 296 should_fail = 0; 297 create_files(); 298 set_file_enforce(0); 299 stage_file_test(); 300 creanup_files(); 301 302 clear_status(); 303 return 0; 304 } 305