diff options
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 114 |
1 files changed, 15 insertions, 99 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 6c2ba69fc89e..df3b203d7d4f 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -265,33 +265,6 @@ static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r) | |||
265 | tomoyo_file_pattern(filename), buffer); | 265 | tomoyo_file_pattern(filename), buffer); |
266 | } | 266 | } |
267 | 267 | ||
268 | /* | ||
269 | * tomoyo_globally_readable_list is used for holding list of pathnames which | ||
270 | * are by default allowed to be open()ed for reading by any process. | ||
271 | * | ||
272 | * An entry is added by | ||
273 | * | ||
274 | * # echo 'allow_read /lib/libc-2.5.so' > \ | ||
275 | * /sys/kernel/security/tomoyo/exception_policy | ||
276 | * | ||
277 | * and is deleted by | ||
278 | * | ||
279 | * # echo 'delete allow_read /lib/libc-2.5.so' > \ | ||
280 | * /sys/kernel/security/tomoyo/exception_policy | ||
281 | * | ||
282 | * and all entries are retrieved by | ||
283 | * | ||
284 | * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy | ||
285 | * | ||
286 | * In the example above, any process is allowed to | ||
287 | * open("/lib/libc-2.5.so", O_RDONLY). | ||
288 | * One exception is, if the domain which current process belongs to is marked | ||
289 | * as "ignore_global_allow_read", current process can't do so unless explicitly | ||
290 | * given "allow_read /lib/libc-2.5.so" to the domain which current process | ||
291 | * belongs to. | ||
292 | */ | ||
293 | LIST_HEAD(tomoyo_globally_readable_list); | ||
294 | |||
295 | static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, | 268 | static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, |
296 | const struct tomoyo_acl_head *b) | 269 | const struct tomoyo_acl_head *b) |
297 | { | 270 | { |
@@ -323,7 +296,8 @@ static int tomoyo_update_globally_readable_entry(const char *filename, | |||
323 | if (!e.filename) | 296 | if (!e.filename) |
324 | return -ENOMEM; | 297 | return -ENOMEM; |
325 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, | 298 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
326 | &tomoyo_globally_readable_list, | 299 | &tomoyo_policy_list |
300 | [TOMOYO_ID_GLOBALLY_READABLE], | ||
327 | tomoyo_same_globally_readable); | 301 | tomoyo_same_globally_readable); |
328 | tomoyo_put_name(e.filename); | 302 | tomoyo_put_name(e.filename); |
329 | return error; | 303 | return error; |
@@ -344,8 +318,8 @@ static bool tomoyo_globally_readable_file(const struct tomoyo_path_info * | |||
344 | struct tomoyo_globally_readable_file_entry *ptr; | 318 | struct tomoyo_globally_readable_file_entry *ptr; |
345 | bool found = false; | 319 | bool found = false; |
346 | 320 | ||
347 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, | 321 | list_for_each_entry_rcu(ptr, &tomoyo_policy_list |
348 | head.list) { | 322 | [TOMOYO_ID_GLOBALLY_READABLE], head.list) { |
349 | if (!ptr->head.is_deleted && | 323 | if (!ptr->head.is_deleted && |
350 | tomoyo_path_matches_pattern(filename, ptr->filename)) { | 324 | tomoyo_path_matches_pattern(filename, ptr->filename)) { |
351 | found = true; | 325 | found = true; |
@@ -385,7 +359,7 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) | |||
385 | bool done = true; | 359 | bool done = true; |
386 | 360 | ||
387 | list_for_each_cookie(pos, head->read_var2, | 361 | list_for_each_cookie(pos, head->read_var2, |
388 | &tomoyo_globally_readable_list) { | 362 | &tomoyo_policy_list[TOMOYO_ID_GLOBALLY_READABLE]) { |
389 | struct tomoyo_globally_readable_file_entry *ptr; | 363 | struct tomoyo_globally_readable_file_entry *ptr; |
390 | ptr = list_entry(pos, | 364 | ptr = list_entry(pos, |
391 | struct tomoyo_globally_readable_file_entry, | 365 | struct tomoyo_globally_readable_file_entry, |
@@ -400,37 +374,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) | |||
400 | return done; | 374 | return done; |
401 | } | 375 | } |
402 | 376 | ||
403 | /* tomoyo_pattern_list is used for holding list of pathnames which are used for | ||
404 | * converting pathnames to pathname patterns during learning mode. | ||
405 | * | ||
406 | * An entry is added by | ||
407 | * | ||
408 | * # echo 'file_pattern /proc/\$/mounts' > \ | ||
409 | * /sys/kernel/security/tomoyo/exception_policy | ||
410 | * | ||
411 | * and is deleted by | ||
412 | * | ||
413 | * # echo 'delete file_pattern /proc/\$/mounts' > \ | ||
414 | * /sys/kernel/security/tomoyo/exception_policy | ||
415 | * | ||
416 | * and all entries are retrieved by | ||
417 | * | ||
418 | * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy | ||
419 | * | ||
420 | * In the example above, if a process which belongs to a domain which is in | ||
421 | * learning mode requested open("/proc/1/mounts", O_RDONLY), | ||
422 | * "allow_read /proc/\$/mounts" is automatically added to the domain which that | ||
423 | * process belongs to. | ||
424 | * | ||
425 | * It is not a desirable behavior that we have to use /proc/\$/ instead of | ||
426 | * /proc/self/ when current process needs to access only current process's | ||
427 | * information. As of now, LSM version of TOMOYO is using __d_path() for | ||
428 | * calculating pathname. Non LSM version of TOMOYO is using its own function | ||
429 | * which pretends as if /proc/self/ is not a symlink; so that we can forbid | ||
430 | * current process from accessing other process's information. | ||
431 | */ | ||
432 | LIST_HEAD(tomoyo_pattern_list); | ||
433 | |||
434 | static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, | 377 | static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, |
435 | const struct tomoyo_acl_head *b) | 378 | const struct tomoyo_acl_head *b) |
436 | { | 379 | { |
@@ -460,7 +403,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern, | |||
460 | if (!e.pattern) | 403 | if (!e.pattern) |
461 | return -ENOMEM; | 404 | return -ENOMEM; |
462 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, | 405 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
463 | &tomoyo_pattern_list, | 406 | &tomoyo_policy_list[TOMOYO_ID_PATTERN], |
464 | tomoyo_same_pattern); | 407 | tomoyo_same_pattern); |
465 | tomoyo_put_name(e.pattern); | 408 | tomoyo_put_name(e.pattern); |
466 | return error; | 409 | return error; |
@@ -480,7 +423,8 @@ const char *tomoyo_file_pattern(const struct tomoyo_path_info *filename) | |||
480 | struct tomoyo_pattern_entry *ptr; | 423 | struct tomoyo_pattern_entry *ptr; |
481 | const struct tomoyo_path_info *pattern = NULL; | 424 | const struct tomoyo_path_info *pattern = NULL; |
482 | 425 | ||
483 | list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, head.list) { | 426 | list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_PATTERN], |
427 | head.list) { | ||
484 | if (ptr->head.is_deleted) | 428 | if (ptr->head.is_deleted) |
485 | continue; | 429 | continue; |
486 | if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) | 430 | if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) |
@@ -527,7 +471,8 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) | |||
527 | struct list_head *pos; | 471 | struct list_head *pos; |
528 | bool done = true; | 472 | bool done = true; |
529 | 473 | ||
530 | list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { | 474 | list_for_each_cookie(pos, head->read_var2, |
475 | &tomoyo_policy_list[TOMOYO_ID_PATTERN]) { | ||
531 | struct tomoyo_pattern_entry *ptr; | 476 | struct tomoyo_pattern_entry *ptr; |
532 | ptr = list_entry(pos, struct tomoyo_pattern_entry, head.list); | 477 | ptr = list_entry(pos, struct tomoyo_pattern_entry, head.list); |
533 | if (ptr->head.is_deleted) | 478 | if (ptr->head.is_deleted) |
@@ -540,37 +485,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) | |||
540 | return done; | 485 | return done; |
541 | } | 486 | } |
542 | 487 | ||
543 | /* | ||
544 | * tomoyo_no_rewrite_list is used for holding list of pathnames which are by | ||
545 | * default forbidden to modify already written content of a file. | ||
546 | * | ||
547 | * An entry is added by | ||
548 | * | ||
549 | * # echo 'deny_rewrite /var/log/messages' > \ | ||
550 | * /sys/kernel/security/tomoyo/exception_policy | ||
551 | * | ||
552 | * and is deleted by | ||
553 | * | ||
554 | * # echo 'delete deny_rewrite /var/log/messages' > \ | ||
555 | * /sys/kernel/security/tomoyo/exception_policy | ||
556 | * | ||
557 | * and all entries are retrieved by | ||
558 | * | ||
559 | * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy | ||
560 | * | ||
561 | * In the example above, if a process requested to rewrite /var/log/messages , | ||
562 | * the process can't rewrite unless the domain which that process belongs to | ||
563 | * has "allow_rewrite /var/log/messages" entry. | ||
564 | * | ||
565 | * It is not a desirable behavior that we have to add "\040(deleted)" suffix | ||
566 | * when we want to allow rewriting already unlink()ed file. As of now, | ||
567 | * LSM version of TOMOYO is using __d_path() for calculating pathname. | ||
568 | * Non LSM version of TOMOYO is using its own function which doesn't append | ||
569 | * " (deleted)" suffix if the file is already unlink()ed; so that we don't | ||
570 | * need to worry whether the file is already unlink()ed or not. | ||
571 | */ | ||
572 | LIST_HEAD(tomoyo_no_rewrite_list); | ||
573 | |||
574 | static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, | 488 | static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, |
575 | const struct tomoyo_acl_head *b) | 489 | const struct tomoyo_acl_head *b) |
576 | { | 490 | { |
@@ -601,7 +515,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern, | |||
601 | if (!e.pattern) | 515 | if (!e.pattern) |
602 | return -ENOMEM; | 516 | return -ENOMEM; |
603 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, | 517 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
604 | &tomoyo_no_rewrite_list, | 518 | &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], |
605 | tomoyo_same_no_rewrite); | 519 | tomoyo_same_no_rewrite); |
606 | tomoyo_put_name(e.pattern); | 520 | tomoyo_put_name(e.pattern); |
607 | return error; | 521 | return error; |
@@ -622,7 +536,8 @@ static bool tomoyo_no_rewrite_file(const struct tomoyo_path_info *filename) | |||
622 | struct tomoyo_no_rewrite_entry *ptr; | 536 | struct tomoyo_no_rewrite_entry *ptr; |
623 | bool found = false; | 537 | bool found = false; |
624 | 538 | ||
625 | list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, head.list) { | 539 | list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE], |
540 | head.list) { | ||
626 | if (ptr->head.is_deleted) | 541 | if (ptr->head.is_deleted) |
627 | continue; | 542 | continue; |
628 | if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) | 543 | if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) |
@@ -662,7 +577,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) | |||
662 | struct list_head *pos; | 577 | struct list_head *pos; |
663 | bool done = true; | 578 | bool done = true; |
664 | 579 | ||
665 | list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { | 580 | list_for_each_cookie(pos, head->read_var2, |
581 | &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE]) { | ||
666 | struct tomoyo_no_rewrite_entry *ptr; | 582 | struct tomoyo_no_rewrite_entry *ptr; |
667 | ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, | 583 | ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, |
668 | head.list); | 584 | head.list); |