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_rewrite_test.c
19 *
20 * Testing program for security/tomoyo/
21 *
22 * Copyright (C) 2005-2010  NTT DATA CORPORATION
23 */
24#include "include.h"
25
26static int should_fail = 0;
27
28static void show_prompt(const char *str)
29{
30	printf("Testing %35s: (%s) ", str,
31	       should_fail ? "must fail" : "must success");
32	errno = 0;
33}
34
35static 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("BUG!\n");
43		} else {
44			printf("BUG!\n");
45		}
46	} else {
47		if (result != EOF)
48			printf("OK\n");
49		else
50			printf("BUG!\n");
51	}
52}
53
54#define REWRITE_PATH "/tmp/rewrite_test"
55
56static void stage_rewrite_test(void)
57{
58	int fd;
59
60	/* Start up */
61	write_domain_policy("allow_read/write " REWRITE_PATH, 0);
62	write_domain_policy("allow_truncate " REWRITE_PATH, 0);
63	write_domain_policy("allow_create " REWRITE_PATH " 0600", 0);
64	write_domain_policy("allow_unlink " REWRITE_PATH, 0);
65	write_exception_policy("deny_rewrite " REWRITE_PATH, 0);
66	set_profile(3, "file::open");
67	set_profile(3, "file::create");
68	set_profile(3, "file::truncate");
69	set_profile(3, "file::rewrite");
70	set_profile(3, "file::unlink");
71	close(open(REWRITE_PATH, O_WRONLY | O_APPEND | O_CREAT, 0600));
72
73	/* Enforce mode */
74	should_fail = 0;
75
76	show_prompt("open(O_RDONLY)");
77	fd = open(REWRITE_PATH, O_RDONLY);
78	show_result(fd);
79	close(fd);
80
81	show_prompt("open(O_WRONLY | O_APPEND)");
82	fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
83	show_result(fd);
84	close(fd);
85
86	should_fail = 1;
87	show_prompt("open(O_WRONLY)");
88	fd = open(REWRITE_PATH, O_WRONLY);
89	show_result(fd);
90	close(fd);
91
92	show_prompt("open(O_WRONLY | O_TRUNC)");
93	fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC);
94	show_result(fd);
95	close(fd);
96
97	show_prompt("open(O_WRONLY | O_TRUNC | O_APPEND)");
98	fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC | O_APPEND);
99	show_result(fd);
100	close(fd);
101
102	show_prompt("truncate()");
103	show_result(truncate(REWRITE_PATH, 0));
104
105	fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
106	show_prompt("ftruncate()");
107	show_result(ftruncate(fd, 0));
108
109	show_prompt("fcntl(F_SETFL, ~O_APPEND)");
110	show_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND));
111	close(fd);
112
113	/* Permissive mode */
114	set_profile(2, "file::open");
115	set_profile(2, "file::create");
116	set_profile(2, "file::truncate");
117	set_profile(2, "file::rewrite");
118	set_profile(2, "file::unlink");
119	should_fail = 0;
120
121	show_prompt("open(O_RDONLY)");
122	fd = open(REWRITE_PATH, O_RDONLY);
123	show_result(fd);
124	close(fd);
125
126	show_prompt("open(O_WRONLY | O_APPEND)");
127	fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
128	show_result(fd);
129	close(fd);
130
131	show_prompt("open(O_WRONLY)");
132	fd = open(REWRITE_PATH, O_WRONLY);
133	show_result(fd);
134	close(fd);
135
136	show_prompt("open(O_WRONLY | O_TRUNC)");
137	fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC);
138	show_result(fd);
139	close(fd);
140
141	show_prompt("open(O_WRONLY | O_TRUNC | O_APPEND)");
142	fd = open(REWRITE_PATH, O_WRONLY | O_TRUNC | O_APPEND);
143	show_result(fd);
144	close(fd);
145
146	show_prompt("truncate()");
147	show_result(truncate(REWRITE_PATH, 0));
148
149	fd = open(REWRITE_PATH, O_WRONLY | O_APPEND);
150	show_prompt("ftruncate()");
151	show_result(ftruncate(fd, 0));
152
153	show_prompt("fcntl(F_SETFL, ~O_APPEND)");
154	show_result(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_APPEND));
155	close(fd);
156
157	/* Clean up */
158	unlink(REWRITE_PATH);
159	write_exception_policy("deny_rewrite " REWRITE_PATH, 0);
160	printf("\n\n");
161}
162
163int main(void)
164{
165	tomoyo_test_init();
166	stage_rewrite_test();
167	clear_status();
168	return 0;
169}
170