diff options
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 107 |
1 files changed, 38 insertions, 69 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 09436d11f298..8015719926d5 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -253,6 +253,15 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename, | |||
253 | */ | 253 | */ |
254 | LIST_HEAD(tomoyo_globally_readable_list); | 254 | LIST_HEAD(tomoyo_globally_readable_list); |
255 | 255 | ||
256 | static bool tomoyo_same_globally_readable(const struct tomoyo_acl_head *a, | ||
257 | const struct tomoyo_acl_head *b) | ||
258 | { | ||
259 | return container_of(a, struct tomoyo_globally_readable_file_entry, | ||
260 | head)->filename == | ||
261 | container_of(b, struct tomoyo_globally_readable_file_entry, | ||
262 | head)->filename; | ||
263 | } | ||
264 | |||
256 | /** | 265 | /** |
257 | * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. | 266 | * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. |
258 | * | 267 | * |
@@ -266,36 +275,17 @@ LIST_HEAD(tomoyo_globally_readable_list); | |||
266 | static int tomoyo_update_globally_readable_entry(const char *filename, | 275 | static int tomoyo_update_globally_readable_entry(const char *filename, |
267 | const bool is_delete) | 276 | const bool is_delete) |
268 | { | 277 | { |
269 | struct tomoyo_globally_readable_file_entry *ptr; | ||
270 | struct tomoyo_globally_readable_file_entry e = { }; | 278 | struct tomoyo_globally_readable_file_entry e = { }; |
271 | int error = is_delete ? -ENOENT : -ENOMEM; | 279 | int error; |
272 | 280 | ||
273 | if (!tomoyo_is_correct_word(filename)) | 281 | if (!tomoyo_is_correct_word(filename)) |
274 | return -EINVAL; | 282 | return -EINVAL; |
275 | e.filename = tomoyo_get_name(filename); | 283 | e.filename = tomoyo_get_name(filename); |
276 | if (!e.filename) | 284 | if (!e.filename) |
277 | return -ENOMEM; | 285 | return -ENOMEM; |
278 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 286 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
279 | goto out; | 287 | &tomoyo_globally_readable_list, |
280 | list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, | 288 | tomoyo_same_globally_readable); |
281 | head.list) { | ||
282 | if (ptr->filename != e.filename) | ||
283 | continue; | ||
284 | ptr->head.is_deleted = is_delete; | ||
285 | error = 0; | ||
286 | break; | ||
287 | } | ||
288 | if (!is_delete && error) { | ||
289 | struct tomoyo_globally_readable_file_entry *entry = | ||
290 | tomoyo_commit_ok(&e, sizeof(e)); | ||
291 | if (entry) { | ||
292 | list_add_tail_rcu(&entry->head.list, | ||
293 | &tomoyo_globally_readable_list); | ||
294 | error = 0; | ||
295 | } | ||
296 | } | ||
297 | mutex_unlock(&tomoyo_policy_lock); | ||
298 | out: | ||
299 | tomoyo_put_name(e.filename); | 289 | tomoyo_put_name(e.filename); |
300 | return error; | 290 | return error; |
301 | } | 291 | } |
@@ -402,6 +392,13 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) | |||
402 | */ | 392 | */ |
403 | LIST_HEAD(tomoyo_pattern_list); | 393 | LIST_HEAD(tomoyo_pattern_list); |
404 | 394 | ||
395 | static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, | ||
396 | const struct tomoyo_acl_head *b) | ||
397 | { | ||
398 | return container_of(a, struct tomoyo_pattern_entry, head)->pattern == | ||
399 | container_of(b, struct tomoyo_pattern_entry, head)->pattern; | ||
400 | } | ||
401 | |||
405 | /** | 402 | /** |
406 | * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. | 403 | * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. |
407 | * | 404 | * |
@@ -415,35 +412,17 @@ LIST_HEAD(tomoyo_pattern_list); | |||
415 | static int tomoyo_update_file_pattern_entry(const char *pattern, | 412 | static int tomoyo_update_file_pattern_entry(const char *pattern, |
416 | const bool is_delete) | 413 | const bool is_delete) |
417 | { | 414 | { |
418 | struct tomoyo_pattern_entry *ptr; | ||
419 | struct tomoyo_pattern_entry e = { }; | 415 | struct tomoyo_pattern_entry e = { }; |
420 | int error = is_delete ? -ENOENT : -ENOMEM; | 416 | int error; |
421 | 417 | ||
422 | if (!tomoyo_is_correct_word(pattern)) | 418 | if (!tomoyo_is_correct_word(pattern)) |
423 | return -EINVAL; | 419 | return -EINVAL; |
424 | e.pattern = tomoyo_get_name(pattern); | 420 | e.pattern = tomoyo_get_name(pattern); |
425 | if (!e.pattern) | 421 | if (!e.pattern) |
426 | return error; | 422 | return -ENOMEM; |
427 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 423 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
428 | goto out; | 424 | &tomoyo_pattern_list, |
429 | list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, head.list) { | 425 | tomoyo_same_pattern); |
430 | if (e.pattern != ptr->pattern) | ||
431 | continue; | ||
432 | ptr->head.is_deleted = is_delete; | ||
433 | error = 0; | ||
434 | break; | ||
435 | } | ||
436 | if (!is_delete && error) { | ||
437 | struct tomoyo_pattern_entry *entry = | ||
438 | tomoyo_commit_ok(&e, sizeof(e)); | ||
439 | if (entry) { | ||
440 | list_add_tail_rcu(&entry->head.list, | ||
441 | &tomoyo_pattern_list); | ||
442 | error = 0; | ||
443 | } | ||
444 | } | ||
445 | mutex_unlock(&tomoyo_policy_lock); | ||
446 | out: | ||
447 | tomoyo_put_name(e.pattern); | 426 | tomoyo_put_name(e.pattern); |
448 | return error; | 427 | return error; |
449 | } | 428 | } |
@@ -553,6 +532,14 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) | |||
553 | */ | 532 | */ |
554 | LIST_HEAD(tomoyo_no_rewrite_list); | 533 | LIST_HEAD(tomoyo_no_rewrite_list); |
555 | 534 | ||
535 | static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, | ||
536 | const struct tomoyo_acl_head *b) | ||
537 | { | ||
538 | return container_of(a, struct tomoyo_no_rewrite_entry, head)->pattern | ||
539 | == container_of(b, struct tomoyo_no_rewrite_entry, head) | ||
540 | ->pattern; | ||
541 | } | ||
542 | |||
556 | /** | 543 | /** |
557 | * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. | 544 | * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. |
558 | * | 545 | * |
@@ -566,35 +553,17 @@ LIST_HEAD(tomoyo_no_rewrite_list); | |||
566 | static int tomoyo_update_no_rewrite_entry(const char *pattern, | 553 | static int tomoyo_update_no_rewrite_entry(const char *pattern, |
567 | const bool is_delete) | 554 | const bool is_delete) |
568 | { | 555 | { |
569 | struct tomoyo_no_rewrite_entry *ptr; | ||
570 | struct tomoyo_no_rewrite_entry e = { }; | 556 | struct tomoyo_no_rewrite_entry e = { }; |
571 | int error = is_delete ? -ENOENT : -ENOMEM; | 557 | int error; |
572 | 558 | ||
573 | if (!tomoyo_is_correct_word(pattern)) | 559 | if (!tomoyo_is_correct_word(pattern)) |
574 | return -EINVAL; | 560 | return -EINVAL; |
575 | e.pattern = tomoyo_get_name(pattern); | 561 | e.pattern = tomoyo_get_name(pattern); |
576 | if (!e.pattern) | 562 | if (!e.pattern) |
577 | return error; | 563 | return -ENOMEM; |
578 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 564 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
579 | goto out; | 565 | &tomoyo_no_rewrite_list, |
580 | list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, head.list) { | 566 | tomoyo_same_no_rewrite); |
581 | if (ptr->pattern != e.pattern) | ||
582 | continue; | ||
583 | ptr->head.is_deleted = is_delete; | ||
584 | error = 0; | ||
585 | break; | ||
586 | } | ||
587 | if (!is_delete && error) { | ||
588 | struct tomoyo_no_rewrite_entry *entry = | ||
589 | tomoyo_commit_ok(&e, sizeof(e)); | ||
590 | if (entry) { | ||
591 | list_add_tail_rcu(&entry->head.list, | ||
592 | &tomoyo_no_rewrite_list); | ||
593 | error = 0; | ||
594 | } | ||
595 | } | ||
596 | mutex_unlock(&tomoyo_policy_lock); | ||
597 | out: | ||
598 | tomoyo_put_name(e.pattern); | 567 | tomoyo_put_name(e.pattern); |
599 | return error; | 568 | return error; |
600 | } | 569 | } |