aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/common.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-03 07:38:44 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:33:43 -0400
commit57c2590fb7fd38bd52708ff2716a577d0c2b3c5a (patch)
tree19db2e176e1e49d85482995249ba18aebbb8f7eb /security/tomoyo/common.c
parent1084307ca097745ed6e40a192329b133a49271ac (diff)
TOMOYO: Update profile structure.
This patch allows users to change access control mode for per-operation basis. This feature comes from non LSM version of TOMOYO which is designed for permitting users to use SELinux and TOMOYO at the same time. SELinux does not care filename in a directory whereas TOMOYO does. Change of filename can change how the file is used. For example, renaming index.txt to .htaccess will change how the file is used. Thus, letting SELinux to enforce read()/write()/mmap() etc. restriction and letting TOMOYO to enforce rename() restriction is an example usage of this feature. What is unfortunate for me is that currently LSM does not allow users to use SELinux and LSM version of TOMOYO at the same time... Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r--security/tomoyo/common.c431
1 files changed, 259 insertions, 172 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index bdf1ed7ca45b..811adb5e9fea 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -9,53 +9,74 @@
9#include <linux/uaccess.h> 9#include <linux/uaccess.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/security.h> 11#include <linux/security.h>
12#include <linux/hardirq.h>
13#include "common.h" 12#include "common.h"
14 13
14static struct tomoyo_profile tomoyo_default_profile = {
15 .learning = &tomoyo_default_profile.preference,
16 .permissive = &tomoyo_default_profile.preference,
17 .enforcing = &tomoyo_default_profile.preference,
18 .preference.enforcing_verbose = true,
19 .preference.learning_max_entry = 2048,
20 .preference.learning_verbose = false,
21 .preference.permissive_verbose = true
22};
23
24/* Profile version. Currently only 20090903 is defined. */
25static unsigned int tomoyo_profile_version;
26
27/* Profile table. Memory is allocated as needed. */
28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
29
15/* String table for functionality that takes 4 modes. */ 30/* String table for functionality that takes 4 modes. */
16static const char *tomoyo_mode_4[4] = { 31static const char *tomoyo_mode_4[4] = {
17 "disabled", "learning", "permissive", "enforcing" 32 "disabled", "learning", "permissive", "enforcing"
18}; 33};
19/* String table for functionality that takes 2 modes. */
20static const char *tomoyo_mode_2[4] = {
21 "disabled", "enabled", "enabled", "enabled"
22};
23 34
24/* 35/* String table for /sys/kernel/security/tomoyo/profile */
25 * tomoyo_control_array is a static data which contains 36static const char *tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
26 * 37 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
27 * (1) functionality name used by /sys/kernel/security/tomoyo/profile . 38 [TOMOYO_MAC_FILE_EXECUTE] = "file::execute",
28 * (2) initial values for "struct tomoyo_profile". 39 [TOMOYO_MAC_FILE_OPEN] = "file::open",
29 * (3) max values for "struct tomoyo_profile". 40 [TOMOYO_MAC_FILE_CREATE] = "file::create",
30 */ 41 [TOMOYO_MAC_FILE_UNLINK] = "file::unlink",
31static struct { 42 [TOMOYO_MAC_FILE_MKDIR] = "file::mkdir",
32 const char *keyword; 43 [TOMOYO_MAC_FILE_RMDIR] = "file::rmdir",
33 unsigned int current_value; 44 [TOMOYO_MAC_FILE_MKFIFO] = "file::mkfifo",
34 const unsigned int max_value; 45 [TOMOYO_MAC_FILE_MKSOCK] = "file::mksock",
35} tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = { 46 [TOMOYO_MAC_FILE_TRUNCATE] = "file::truncate",
36 [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 }, 47 [TOMOYO_MAC_FILE_SYMLINK] = "file::symlink",
37 [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX }, 48 [TOMOYO_MAC_FILE_REWRITE] = "file::rewrite",
38 [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 }, 49 [TOMOYO_MAC_FILE_MKBLOCK] = "file::mkblock",
50 [TOMOYO_MAC_FILE_MKCHAR] = "file::mkchar",
51 [TOMOYO_MAC_FILE_LINK] = "file::link",
52 [TOMOYO_MAC_FILE_RENAME] = "file::rename",
53 [TOMOYO_MAC_FILE_CHMOD] = "file::chmod",
54 [TOMOYO_MAC_FILE_CHOWN] = "file::chown",
55 [TOMOYO_MAC_FILE_CHGRP] = "file::chgrp",
56 [TOMOYO_MAC_FILE_IOCTL] = "file::ioctl",
57 [TOMOYO_MAC_FILE_CHROOT] = "file::chroot",
58 [TOMOYO_MAC_FILE_MOUNT] = "file::mount",
59 [TOMOYO_MAC_FILE_UMOUNT] = "file::umount",
60 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "file::pivot_root",
61 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
39}; 62};
40 63
41/*
42 * tomoyo_profile is a structure which is used for holding the mode of access
43 * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
44 * An administrator can define up to 256 profiles.
45 * The ->profile of "struct tomoyo_domain_info" is used for remembering
46 * the profile's number (0 - 255) assigned to that domain.
47 */
48static struct tomoyo_profile {
49 unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
50 const struct tomoyo_path_info *comment;
51} *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
52
53/* Permit policy management by non-root user? */ 64/* Permit policy management by non-root user? */
54static bool tomoyo_manage_by_non_root; 65static bool tomoyo_manage_by_non_root;
55 66
56/* Utility functions. */ 67/* Utility functions. */
57 68
58/** 69/**
70 * tomoyo_yesno - Return "yes" or "no".
71 *
72 * @value: Bool value.
73 */
74static const char *tomoyo_yesno(const unsigned int value)
75{
76 return value ? "yes" : "no";
77}
78
79/**
59 * tomoyo_print_name_union - Print a tomoyo_name_union. 80 * tomoyo_print_name_union - Print a tomoyo_name_union.
60 * 81 *
61 * @head: Pointer to "struct tomoyo_io_buffer". 82 * @head: Pointer to "struct tomoyo_io_buffer".
@@ -154,80 +175,62 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
154} 175}
155 176
156/** 177/**
157 * tomoyo_check_flags - Check mode for specified functionality.
158 *
159 * @domain: Pointer to "struct tomoyo_domain_info".
160 * @index: The functionality to check mode.
161 *
162 * TOMOYO checks only process context.
163 * This code disables TOMOYO's enforcement in case the function is called from
164 * interrupt context.
165 */
166unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
167 const u8 index)
168{
169 const u8 profile = domain->profile;
170
171 if (WARN_ON(in_interrupt()))
172 return 0;
173 return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX
174#if TOMOYO_MAX_PROFILES != 256
175 && profile < TOMOYO_MAX_PROFILES
176#endif
177 && tomoyo_profile_ptr[profile] ?
178 tomoyo_profile_ptr[profile]->value[index] : 0;
179}
180
181/**
182 * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode.
183 *
184 * @domain: Pointer to "struct tomoyo_domain_info".
185 *
186 * Returns true if domain policy violation warning should be printed to
187 * console.
188 */
189bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
190{
191 return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0;
192}
193
194/**
195 * tomoyo_find_or_assign_new_profile - Create a new profile. 178 * tomoyo_find_or_assign_new_profile - Create a new profile.
196 * 179 *
197 * @profile: Profile number to create. 180 * @profile: Profile number to create.
198 * 181 *
199 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 182 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
200 */ 183 */
201static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned 184static struct tomoyo_profile *tomoyo_find_or_assign_new_profile
202 int profile) 185(const unsigned int profile)
203{ 186{
204 struct tomoyo_profile *ptr = NULL; 187 struct tomoyo_profile *ptr;
205 int i; 188 struct tomoyo_profile *entry;
206
207 if (profile >= TOMOYO_MAX_PROFILES) 189 if (profile >= TOMOYO_MAX_PROFILES)
208 return NULL; 190 return NULL;
209 if (mutex_lock_interruptible(&tomoyo_policy_lock))
210 return NULL;
211 ptr = tomoyo_profile_ptr[profile]; 191 ptr = tomoyo_profile_ptr[profile];
212 if (ptr) 192 if (ptr)
213 goto ok; 193 return ptr;
214 ptr = kmalloc(sizeof(*ptr), GFP_NOFS); 194 entry = kzalloc(sizeof(*entry), GFP_NOFS);
215 if (!tomoyo_memory_ok(ptr)) { 195 if (mutex_lock_interruptible(&tomoyo_policy_lock))
216 kfree(ptr); 196 goto out;
217 ptr = NULL; 197 ptr = tomoyo_profile_ptr[profile];
218 goto ok; 198 if (!ptr && tomoyo_memory_ok(entry)) {
199 ptr = entry;
200 ptr->learning = &tomoyo_default_profile.preference;
201 ptr->permissive = &tomoyo_default_profile.preference;
202 ptr->enforcing = &tomoyo_default_profile.preference;
203 ptr->default_config = TOMOYO_CONFIG_DISABLED;
204 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
205 sizeof(ptr->config));
206 mb(); /* Avoid out-of-order execution. */
207 tomoyo_profile_ptr[profile] = ptr;
208 entry = NULL;
219 } 209 }
220 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
221 ptr->value[i] = tomoyo_control_array[i].current_value;
222 mb(); /* Avoid out-of-order execution. */
223 tomoyo_profile_ptr[profile] = ptr;
224 ok:
225 mutex_unlock(&tomoyo_policy_lock); 210 mutex_unlock(&tomoyo_policy_lock);
211 out:
212 kfree(entry);
226 return ptr; 213 return ptr;
227} 214}
228 215
229/** 216/**
230 * tomoyo_write_profile - Write to profile table. 217 * tomoyo_profile - Find a profile.
218 *
219 * @profile: Profile number to find.
220 *
221 * Returns pointer to "struct tomoyo_profile".
222 */
223struct tomoyo_profile *tomoyo_profile(const u8 profile)
224{
225 struct tomoyo_profile *ptr = tomoyo_profile_ptr[profile];
226 if (!tomoyo_policy_loaded)
227 return &tomoyo_default_profile;
228 BUG_ON(!ptr);
229 return ptr;
230}
231
232/**
233 * tomoyo_write_profile - Write profile table.
231 * 234 *
232 * @head: Pointer to "struct tomoyo_io_buffer". 235 * @head: Pointer to "struct tomoyo_io_buffer".
233 * 236 *
@@ -237,64 +240,116 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
237{ 240{
238 char *data = head->write_buf; 241 char *data = head->write_buf;
239 unsigned int i; 242 unsigned int i;
240 unsigned int value; 243 int value;
244 int mode;
245 u8 config;
246 bool use_default = false;
241 char *cp; 247 char *cp;
242 struct tomoyo_profile *profile; 248 struct tomoyo_profile *profile;
243 unsigned long num; 249 if (sscanf(data, "PROFILE_VERSION=%u", &tomoyo_profile_version) == 1)
244 250 return 0;
245 cp = strchr(data, '-'); 251 i = simple_strtoul(data, &cp, 10);
246 if (cp) 252 if (data == cp) {
247 *cp = '\0'; 253 profile = &tomoyo_default_profile;
248 if (strict_strtoul(data, 10, &num)) 254 } else {
249 return -EINVAL; 255 if (*cp != '-')
250 if (cp) 256 return -EINVAL;
251 data = cp + 1; 257 data = cp + 1;
252 profile = tomoyo_find_or_assign_new_profile(num); 258 profile = tomoyo_find_or_assign_new_profile(i);
253 if (!profile) 259 if (!profile)
254 return -EINVAL; 260 return -EINVAL;
261 }
255 cp = strchr(data, '='); 262 cp = strchr(data, '=');
256 if (!cp) 263 if (!cp)
257 return -EINVAL; 264 return -EINVAL;
258 *cp = '\0'; 265 *cp++ = '\0';
266 if (profile != &tomoyo_default_profile)
267 use_default = strstr(cp, "use_default") != NULL;
268 if (strstr(cp, "verbose=yes"))
269 value = 1;
270 else if (strstr(cp, "verbose=no"))
271 value = 0;
272 else
273 value = -1;
274 if (!strcmp(data, "PREFERENCE::enforcing")) {
275 if (use_default) {
276 profile->enforcing = &tomoyo_default_profile.preference;
277 return 0;
278 }
279 profile->enforcing = &profile->preference;
280 if (value >= 0)
281 profile->preference.enforcing_verbose = value;
282 return 0;
283 }
284 if (!strcmp(data, "PREFERENCE::permissive")) {
285 if (use_default) {
286 profile->permissive = &tomoyo_default_profile.preference;
287 return 0;
288 }
289 profile->permissive = &profile->preference;
290 if (value >= 0)
291 profile->preference.permissive_verbose = value;
292 return 0;
293 }
294 if (!strcmp(data, "PREFERENCE::learning")) {
295 char *cp2;
296 if (use_default) {
297 profile->learning = &tomoyo_default_profile.preference;
298 return 0;
299 }
300 profile->learning = &profile->preference;
301 if (value >= 0)
302 profile->preference.learning_verbose = value;
303 cp2 = strstr(cp, "max_entry=");
304 if (cp2)
305 sscanf(cp2 + 10, "%u",
306 &profile->preference.learning_max_entry);
307 return 0;
308 }
309 if (profile == &tomoyo_default_profile)
310 return -EINVAL;
259 if (!strcmp(data, "COMMENT")) { 311 if (!strcmp(data, "COMMENT")) {
260 const struct tomoyo_path_info *old_comment = profile->comment; 312 const struct tomoyo_path_info *old_comment = profile->comment;
261 profile->comment = tomoyo_get_name(cp + 1); 313 profile->comment = tomoyo_get_name(cp);
262 tomoyo_put_name(old_comment); 314 tomoyo_put_name(old_comment);
263 return 0; 315 return 0;
264 } 316 }
265 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 317 if (!strcmp(data, "CONFIG")) {
266 if (strcmp(data, tomoyo_control_array[i].keyword)) 318 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
267 continue; 319 config = profile->default_config;
268 if (sscanf(cp + 1, "%u", &value) != 1) { 320 } else if (tomoyo_str_starts(&data, "CONFIG::")) {
269 int j; 321 config = 0;
270 const char **modes; 322 for (i = 0; i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
271 switch (i) { 323 if (strcmp(data, tomoyo_mac_keywords[i]))
272 case TOMOYO_VERBOSE: 324 continue;
273 modes = tomoyo_mode_2; 325 config = profile->config[i];
274 break; 326 break;
275 default:
276 modes = tomoyo_mode_4;
277 break;
278 }
279 for (j = 0; j < 4; j++) {
280 if (strcmp(cp + 1, modes[j]))
281 continue;
282 value = j;
283 break;
284 }
285 if (j == 4)
286 return -EINVAL;
287 } else if (value > tomoyo_control_array[i].max_value) {
288 value = tomoyo_control_array[i].max_value;
289 } 327 }
290 profile->value[i] = value; 328 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
291 return 0; 329 return -EINVAL;
330 } else {
331 return -EINVAL;
292 } 332 }
293 return -EINVAL; 333 if (use_default) {
334 config = TOMOYO_CONFIG_USE_DEFAULT;
335 } else {
336 for (mode = 3; mode >= 0; mode--)
337 if (strstr(cp, tomoyo_mode_4[mode]))
338 /*
339 * Update lower 3 bits in order to distinguish
340 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
341 */
342 config = (config & ~7) | mode;
343 }
344 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
345 profile->config[i] = config;
346 else if (config != TOMOYO_CONFIG_USE_DEFAULT)
347 profile->default_config = config;
348 return 0;
294} 349}
295 350
296/** 351/**
297 * tomoyo_read_profile - Read from profile table. 352 * tomoyo_read_profile - Read profile table.
298 * 353 *
299 * @head: Pointer to "struct tomoyo_io_buffer". 354 * @head: Pointer to "struct tomoyo_io_buffer".
300 * 355 *
@@ -302,53 +357,82 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
302 */ 357 */
303static int tomoyo_read_profile(struct tomoyo_io_buffer *head) 358static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
304{ 359{
305 static const int total = TOMOYO_MAX_CONTROL_INDEX + 1; 360 int index;
306 int step;
307
308 if (head->read_eof) 361 if (head->read_eof)
309 return 0; 362 return 0;
310 for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total; 363 if (head->read_bit)
311 step++) { 364 goto body;
312 const u8 index = step / total; 365 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
313 u8 type = step % total; 366 tomoyo_io_printf(head, "PREFERENCE::learning={ verbose=%s "
367 "max_entry=%u }\n",
368 tomoyo_yesno(tomoyo_default_profile.preference.
369 learning_verbose),
370 tomoyo_default_profile.preference.learning_max_entry);
371 tomoyo_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n",
372 tomoyo_yesno(tomoyo_default_profile.preference.
373 permissive_verbose));
374 tomoyo_io_printf(head, "PREFERENCE::enforcing={ verbose=%s }\n",
375 tomoyo_yesno(tomoyo_default_profile.preference.
376 enforcing_verbose));
377 head->read_bit = 1;
378 body:
379 for (index = head->read_step; index < TOMOYO_MAX_PROFILES; index++) {
380 bool done;
381 u8 config;
382 int i;
383 int pos;
314 const struct tomoyo_profile *profile 384 const struct tomoyo_profile *profile
315 = tomoyo_profile_ptr[index]; 385 = tomoyo_profile_ptr[index];
316 head->read_step = step; 386 const struct tomoyo_path_info *comment;
387 head->read_step = index;
317 if (!profile) 388 if (!profile)
318 continue; 389 continue;
319 if (!type) { /* Print profile' comment tag. */ 390 pos = head->read_avail;
320 if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n", 391 comment = profile->comment;
321 index, profile->comment ? 392 done = tomoyo_io_printf(head, "%u-COMMENT=%s\n", index,
322 profile->comment->name : "")) 393 comment ? comment->name : "");
323 break; 394 if (!done)
324 continue; 395 goto out;
325 } 396 config = profile->default_config;
326 type--; 397 if (!tomoyo_io_printf(head, "%u-CONFIG={ mode=%s }\n", index,
327 if (type < TOMOYO_MAX_CONTROL_INDEX) { 398 tomoyo_mode_4[config & 3]))
328 const unsigned int value = profile->value[type]; 399 goto out;
329 const char **modes = NULL; 400 for (i = 0; i < TOMOYO_MAX_MAC_INDEX +
330 const char *keyword 401 TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
331 = tomoyo_control_array[type].keyword; 402 config = profile->config[i];
332 switch (tomoyo_control_array[type].max_value) { 403 if (config == TOMOYO_CONFIG_USE_DEFAULT)
333 case 3: 404 continue;
334 modes = tomoyo_mode_4; 405 if (!tomoyo_io_printf(head,
335 break; 406 "%u-CONFIG::%s={ mode=%s }\n",
336 case 1: 407 index, tomoyo_mac_keywords[i],
337 modes = tomoyo_mode_2; 408 tomoyo_mode_4[config & 3]))
338 break; 409 goto out;
339 }
340 if (modes) {
341 if (!tomoyo_io_printf(head, "%u-%s=%s\n", index,
342 keyword, modes[value]))
343 break;
344 } else {
345 if (!tomoyo_io_printf(head, "%u-%s=%u\n", index,
346 keyword, value))
347 break;
348 }
349 } 410 }
411 if (profile->learning != &tomoyo_default_profile.preference &&
412 !tomoyo_io_printf(head, "%u-PREFERENCE::learning={ "
413 "verbose=%s max_entry=%u }\n", index,
414 tomoyo_yesno(profile->preference.
415 learning_verbose),
416 profile->preference.learning_max_entry))
417 goto out;
418 if (profile->permissive != &tomoyo_default_profile.preference
419 && !tomoyo_io_printf(head, "%u-PREFERENCE::permissive={ "
420 "verbose=%s }\n", index,
421 tomoyo_yesno(profile->preference.
422 permissive_verbose)))
423 goto out;
424 if (profile->enforcing != &tomoyo_default_profile.preference &&
425 !tomoyo_io_printf(head, "%u-PREFERENCE::enforcing={ "
426 "verbose=%s }\n", index,
427 tomoyo_yesno(profile->preference.
428 enforcing_verbose)))
429 goto out;
430 continue;
431 out:
432 head->read_avail = pos;
433 break;
350 } 434 }
351 if (step == TOMOYO_MAX_PROFILES * total) 435 if (index == TOMOYO_MAX_PROFILES)
352 head->read_eof = true; 436 head->read_eof = true;
353 return 0; 437 return 0;
354} 438}
@@ -1595,7 +1679,7 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1595static int tomoyo_read_version(struct tomoyo_io_buffer *head) 1679static int tomoyo_read_version(struct tomoyo_io_buffer *head)
1596{ 1680{
1597 if (!head->read_eof) { 1681 if (!head->read_eof) {
1598 tomoyo_io_printf(head, "2.2.0"); 1682 tomoyo_io_printf(head, "2.3.0-pre");
1599 head->read_eof = true; 1683 head->read_eof = true;
1600 } 1684 }
1601 return 0; 1685 return 0;
@@ -1915,6 +1999,9 @@ void tomoyo_check_profile(void)
1915 profile, domain->domainname->name); 1999 profile, domain->domainname->name);
1916 } 2000 }
1917 tomoyo_read_unlock(idx); 2001 tomoyo_read_unlock(idx);
1918 printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n"); 2002 if (tomoyo_profile_version != 20090903)
2003 panic("Profile version %u is not supported.\n",
2004 tomoyo_profile_version);
2005 printk(KERN_INFO "TOMOYO: 2.3.0-pre 2010/06/03\n");
1919 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2006 printk(KERN_INFO "Mandatory Access Control activated.\n");
1920} 2007}