Home | History | Annotate | Download | only in tomoyo
      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_policy_memory_test.c
     19  *
     20  * Testing program for security/tomoyo/
     21  *
     22  * Copyright (C) 2005-2010  NTT DATA CORPORATION
     23  */
     24 /*
     25  * Usage: Run this program using init= boot option.
     26  */
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 #include <unistd.h>
     31 #include <sys/mount.h>
     32 
     33 static void BUG(const char *msg)
     34 {
     35 	printf("%s", msg);
     36 	fflush(stdout);
     37 	while (1)
     38 		sleep(100);
     39 }
     40 
     41 static const char *policy_file = NULL;
     42 static const char *policy = NULL;
     43 
     44 static void get_meminfo(unsigned int *policy_memory)
     45 {
     46 	FILE *fp = fopen("/sys/kernel/security/tomoyo/meminfo", "r");
     47 	if (!fp || fscanf(fp, "Policy: %u", policy_memory) != 1 || fclose(fp))
     48 		BUG("BUG: Policy read error\n");
     49 }
     50 
     51 static void check_policy_common(const int found_expected, const int id)
     52 {
     53 	FILE *fp = fopen(policy_file, "r");
     54 	char buffer[8192];
     55 	int policy_found = 0;
     56 	memset(buffer, 0, sizeof(buffer));
     57 	if (!fp)
     58 		BUG("BUG: Policy read error\n");
     59 	while (fgets(buffer, sizeof(buffer) - 1, fp)) {
     60 		char *cp = strchr(buffer, '\n');
     61 		if (cp)
     62 			*cp = '\0';
     63 		if (strcmp(buffer, policy))
     64 			continue;
     65 		policy_found = 1;
     66 		break;
     67 	}
     68 	fclose(fp);
     69 	if (policy_found != found_expected) {
     70 		printf("BUG: Policy write error: %s %s at %d\n", policy,
     71 		       found_expected ? "not added" : "not deleted", id);
     72 		BUG("");
     73 	}
     74 }
     75 
     76 static inline void check_policy_written(FILE * fp, const int id)
     77 {
     78 	fflush(fp);
     79 	check_policy_common(1, id);
     80 }
     81 
     82 static inline void check_policy_deleted(FILE * fp, const int id)
     83 {
     84 	fflush(fp);
     85 	check_policy_common(0, id);
     86 }
     87 
     88 static const char *domain_testcases[] = {
     89 	"allow_create /tmp/mknod_reg_test 0600",
     90 	"allow_create /tmp/open_test 0600",
     91 	"allow_create /tmp/open_test 0600",
     92 	"allow_create /tmp/open_test 0600",
     93 	"allow_execute /bin/true",
     94 	"allow_execute /bin/true",
     95 	"allow_execute /bin/true0",
     96 	"allow_execute /bin/true1",
     97 	"allow_execute /bin/true2",
     98 	"allow_execute /bin/true3",
     99 	"allow_execute /bin/true4",
    100 	"allow_execute /bin/true5",
    101 	"allow_execute /bin/true6",
    102 	"allow_execute /bin/true7",
    103 	"allow_execute /bin/true7",
    104 	"allow_execute /bin/true7",
    105 	"allow_execute /bin/true8",
    106 	"allow_ioctl socket:[family=2:type=2:protocol=17] 0-35122",
    107 	"allow_ioctl socket:[family=2:type=2:protocol=17] 35122-35124",
    108 	"allow_link /tmp/link_source_test /tmp/link_dest_test",
    109 	"allow_mkblock /tmp/mknod_blk_test 0600 1 0",
    110 	"allow_mkchar /tmp/mknod_chr_test 0600 1 3",
    111 	"allow_mkdir /tmp/mkdir_test/ 0755",
    112 	"allow_mkfifo /tmp/mknod_fifo_test 0600",
    113 	"allow_mkfifo /tmp/mknod_fifo_test 0600",
    114 	"allow_mksock /tmp/mknod_sock_test 0600",
    115 	"allow_mksock /tmp/socket_test 0600",
    116 	"allow_read /bin/true",
    117 	"allow_read /bin/true",
    118 	"allow_read /dev/null",
    119 	"allow_read /dev/null",
    120 	"allow_read /dev/null",
    121 	"allow_read /dev/null",
    122 	"allow_read /dev/null",
    123 	"allow_read /dev/null",
    124 	"allow_read /foo",
    125 	"allow_read /proc/sys/net/ipv4/ip_local_port_range",
    126 	"allow_read /proc/sys/net/ipv4/ip_local_port_range",
    127 	"allow_read/write /bar",
    128 	"allow_read/write /dev/null",
    129 	"allow_read/write /dev/null",
    130 	"allow_read/write /proc/sys/net/ipv4/ip_local_port_range",
    131 	"allow_read/write /proc/sys/net/ipv4/ip_local_port_range",
    132 	"allow_read/write /tmp/fifo",
    133 	"allow_read/write /tmp/fifo",
    134 	"allow_read/write /tmp/rewrite_test",
    135 	"allow_rename /tmp/rename_source_test /tmp/rename_dest_test",
    136 	"allow_rmdir /tmp/rmdir_test/",
    137 	"allow_symlink /symlink",
    138 	"allow_symlink /symlink",
    139 	"allow_symlink /symlink",
    140 	"allow_symlink /symlink",
    141 	"allow_symlink /tmp/symlink_source_test",
    142 	"allow_symlink /tmp/symlink_source_test",
    143 	"allow_symlink /tmp/symlink_source_test",
    144 	"allow_symlink /tmp/symlink_source_test",
    145 	"allow_symlink /tmp/symlink_source_test",
    146 	"allow_truncate /tmp/rewrite_test",
    147 	"allow_truncate /tmp/truncate_test",
    148 	"allow_truncate /tmp/truncate_test",
    149 	"allow_unlink /tmp/unlink_test",
    150 	"allow_write /123",
    151 	"allow_write /dev/null",
    152 	"allow_write /dev/null",
    153 	"allow_write /devfile",
    154 	"allow_write /devfile",
    155 	"allow_write /proc/sys/net/ipv4/ip_local_port_range",
    156 	"allow_write /proc/sys/net/ipv4/ip_local_port_range",
    157 	"allow_write /tmp/open_test",
    158 	"allow_write /tmp/open_test",
    159 	"allow_write /tmp/open_test",
    160 	"allow_write /tmp/truncate_test",
    161 	"allow_write /tmp/truncate_test",
    162 	"allow_rewrite /tmp/rewrite_test",
    163 	"allow_rewrite /tmp/rewrite_test",
    164 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 0x123",
    165 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 123",
    166 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 0123",
    167 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 0x123",
    168 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 123",
    169 	"allow_mount /dev/sda1 /mnt/sda1/ ext3 0123",
    170 	"allow_chroot /",
    171 	"allow_chroot /",
    172 	"allow_chroot /mnt/",
    173 	"allow_pivot_root / /proc/",
    174 	"allow_pivot_root /mnt/ /proc/mnt/",
    175 	"allow_unmount /",
    176 	"allow_unmount /proc/",
    177 	NULL
    178 };
    179 
    180 static void domain_policy_test(const unsigned int before)
    181 {
    182 	unsigned int after;
    183 	int j;
    184 	policy_file = "/sys/kernel/security/tomoyo/domain_policy";
    185 	for (j = 0; domain_testcases[j]; j++) {
    186 		int i;
    187 		FILE *fp = fopen(policy_file, "w");
    188 		if (!fp)
    189 			BUG("BUG: Policy write error\n");
    190 		fprintf(fp, "<kernel>\n");
    191 		policy = domain_testcases[j];
    192 		printf("Processing: %s\n", policy);
    193 		for (i = 0; i < 100; i++) {
    194 			fprintf(fp, "%s\n", policy);
    195 			if (!i)
    196 				check_policy_written(fp, 1);
    197 			fprintf(fp, "delete %s\n", policy);
    198 		}
    199 		check_policy_deleted(fp, 1);
    200 		for (i = 0; i < 100; i++)
    201 			fprintf(fp, "%s\n", policy);
    202 		check_policy_written(fp, 2);
    203 		fprintf(fp, "delete %s\n", policy);
    204 		check_policy_deleted(fp, 2);
    205 		fclose(fp);
    206 		for (i = 0; i < 30; i++) {
    207 			usleep(100000);
    208 			get_meminfo(&after);
    209 			if (before == after)
    210 				break;
    211 		}
    212 		if (before != after) {
    213 			printf("Policy: %d\n", after - before);
    214 			BUG("Policy read/write test: Fail\n");
    215 		}
    216 	}
    217 	for (j = 0; j < 10; j++) {
    218 		int i;
    219 		FILE *fp = fopen(policy_file, "w");
    220 		if (!fp)
    221 			BUG("BUG: Policy write error\n");
    222 		fprintf(fp, "<kernel> /sbin/init\n");
    223 		for (i = 0; domain_testcases[i]; i++)
    224 			fprintf(fp, "%s\n", domain_testcases[i]);
    225 		fprintf(fp, "delete <kernel> /sbin/init\n");
    226 		fclose(fp);
    227 		for (i = 0; i < 50; i++) {
    228 			usleep(100000);
    229 			get_meminfo(&after);
    230 			if (before == after)
    231 				break;
    232 		}
    233 		if (before != after) {
    234 			printf("Policy: %d\n", after - before);
    235 			BUG("Policy read/write test: Fail\n");
    236 		}
    237 	}
    238 }
    239 
    240 static const char *exception_testcases[] = {
    241 	"allow_read /tmp/mknod_reg_test",
    242 	"allow_env HOME",
    243 	"path_group PG1 /",
    244 	"path_group PG2 /",
    245 	"address_group AG3 0.0.0.0",
    246 	"address_group AG3 1.2.3.4-5.6.7.8",
    247 	"address_group AG3 f:ee:ddd:cccc:b:aa:999:8888",
    248 	"address_group AG4 0:1:2:3:4:5:6:7-8:90:a00:b000:c00:d0:e:f000",
    249 	"number_group NG1 1000",
    250 	"number_group NG2 10-0x100000",
    251 	"number_group NG3 01234567-0xABCDEF89",
    252 	"deny_autobind 1024",
    253 	"deny_autobind 32668-65535",
    254 	"deny_autobind 0-1023",
    255 	"initialize_domain /usr/sbin/sshd",
    256 	"no_initialize_domain /usr/sbin/sshd",
    257 	"initialize_domain /usr/sbin/sshd from /bin/bash",
    258 	"no_initialize_domain /usr/sbin/sshd from /bin/bash",
    259 	"initialize_domain /usr/sbin/sshd from "
    260 	    "<kernel> /bin/mingetty/bin/bash",
    261 	"no_initialize_domain /usr/sbin/sshd from "
    262 	    "<kernel> /bin/mingetty/bin/bash",
    263 	"keep_domain <kernel> /usr/sbin/sshd /bin/bash",
    264 	"no_keep_domain <kernel> /usr/sbin/sshd /bin/bash",
    265 	"keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash",
    266 	"no_keep_domain /bin/pwd from <kernel> /usr/sbin/sshd /bin/bash",
    267 	"keep_domain /bin/pwd from /bin/bash",
    268 	"no_keep_domain /bin/pwd from /bin/bash",
    269 	"file_pattern /proc/\\$/task/\\$/environ",
    270 	"file_pattern /proc/\\$/task/\\$/auxv",
    271 	"allow_read /etc/ld.so.cache",
    272 	"allow_read /proc/meminfo",
    273 	"allow_read /proc/sys/kernel/version",
    274 	"allow_read /etc/localtime",
    275 	"allow_read /proc/self/task/\\$/attr/current",
    276 	"allow_read /proc/self/task/\\$/oom_score",
    277 	"allow_read /proc/self/wchan",
    278 	"allow_read /lib/ld-2.5.so",
    279 	"file_pattern pipe:[\\$]",
    280 	"file_pattern socket:[\\$]",
    281 	"file_pattern /var/cache/logwatch/logwatch.\\*/",
    282 	"file_pattern /var/cache/logwatch/logwatch.\\*/\\*",
    283 	"deny_rewrite /var/log/\\*",
    284 	"deny_rewrite /var/log/\\*/\\*",
    285 	"aggregator /etc/rc.d/rc\\?.d/\\?\\+\\+smb /etc/rc.d/init.d/smb",
    286 	"aggregator /etc/rc.d/rc\\?.d/\\?\\+\\+crond /etc/rc.d/init.d/crond",
    287 	NULL
    288 };
    289 
    290 static void exception_policy_test(const unsigned int before)
    291 {
    292 	unsigned int after;
    293 	int j;
    294 	policy_file = "/sys/kernel/security/tomoyo/exception_policy";
    295 	for (j = 0; exception_testcases[j]; j++) {
    296 		int i;
    297 		FILE *fp = fopen(policy_file, "w");
    298 		if (!fp)
    299 			BUG("BUG: Policy write error\n");
    300 		policy = exception_testcases[j];
    301 		printf("Processing: %s\n", policy);
    302 		for (i = 0; i < 100; i++) {
    303 			fprintf(fp, "%s\n", policy);
    304 			if (!i)
    305 				check_policy_written(fp, 1);
    306 			fprintf(fp, "delete %s\n", policy);
    307 		}
    308 		check_policy_deleted(fp, 1);
    309 		for (i = 0; i < 100; i++)
    310 			fprintf(fp, "%s\n", policy);
    311 		check_policy_written(fp, 2);
    312 		fprintf(fp, "delete %s\n", policy);
    313 		check_policy_deleted(fp, 2);
    314 		fclose(fp);
    315 		for (i = 0; i < 30; i++) {
    316 			usleep(100000);
    317 			get_meminfo(&after);
    318 			if (before == after)
    319 				break;
    320 		}
    321 		if (before != after) {
    322 			printf("Policy: %d\n", after - before);
    323 			BUG("Policy read/write test: Fail\n");
    324 		}
    325 	}
    326 	for (j = 0; j < 10; j++) {
    327 		int i;
    328 		FILE *fp = fopen(policy_file, "w");
    329 		if (!fp)
    330 			BUG("BUG: Policy write error\n");
    331 		for (i = 0; exception_testcases[i]; i++)
    332 			fprintf(fp, "%s\n", exception_testcases[i]);
    333 		for (i = 0; exception_testcases[i]; i++)
    334 			fprintf(fp, "delete %s\n", exception_testcases[i]);
    335 		fclose(fp);
    336 		for (i = 0; i < 50; i++) {
    337 			usleep(100000);
    338 			get_meminfo(&after);
    339 			if (before == after)
    340 				break;
    341 		}
    342 		if (before != after) {
    343 			printf("Policy: %d\n", after - before);
    344 			BUG("Policy read/write test: Fail\n");
    345 		}
    346 	}
    347 }
    348 
    349 int main(int argc, char *argv[])
    350 {
    351 	unsigned int before;
    352 	mount("/proc", "/proc/", "proc", 0, NULL);
    353 	get_meminfo(&before);
    354 	domain_policy_test(before);
    355 	exception_policy_test(before);
    356 	BUG("Policy read/write test: Success\n");
    357 	return 0;
    358 }
    359