diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-07-08 00:24:54 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-07-10 21:05:33 -0400 |
commit | 5b636857fee642694e287e3a181b523b16098c93 (patch) | |
tree | 24afcc11fc35350a29f5d6d73d376a551c5569b8 /security/tomoyo/domain.c | |
parent | 2ca9bf453bdd478bcb6c01aa2d0bd4c2f4350563 (diff) |
TOMOYO: Allow using argv[]/envp[] of execve() as conditions.
This patch adds support for permission checks using argv[]/envp[] of execve()
request. Hooks are in the last patch of this pathset.
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/domain.c')
-rw-r--r-- | security/tomoyo/domain.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 0f02c7852090..565249c42e39 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -713,3 +713,49 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) | |||
713 | kfree(tmp); | 713 | kfree(tmp); |
714 | return retval; | 714 | return retval; |
715 | } | 715 | } |
716 | |||
717 | /** | ||
718 | * tomoyo_dump_page - Dump a page to buffer. | ||
719 | * | ||
720 | * @bprm: Pointer to "struct linux_binprm". | ||
721 | * @pos: Location to dump. | ||
722 | * @dump: Poiner to "struct tomoyo_page_dump". | ||
723 | * | ||
724 | * Returns true on success, false otherwise. | ||
725 | */ | ||
726 | bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, | ||
727 | struct tomoyo_page_dump *dump) | ||
728 | { | ||
729 | struct page *page; | ||
730 | /* dump->data is released by tomoyo_finish_execve(). */ | ||
731 | if (!dump->data) { | ||
732 | dump->data = kzalloc(PAGE_SIZE, GFP_NOFS); | ||
733 | if (!dump->data) | ||
734 | return false; | ||
735 | } | ||
736 | /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */ | ||
737 | #ifdef CONFIG_MMU | ||
738 | if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) | ||
739 | return false; | ||
740 | #else | ||
741 | page = bprm->page[pos / PAGE_SIZE]; | ||
742 | #endif | ||
743 | if (page != dump->page) { | ||
744 | const unsigned int offset = pos % PAGE_SIZE; | ||
745 | /* | ||
746 | * Maybe kmap()/kunmap() should be used here. | ||
747 | * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic(). | ||
748 | * So do I. | ||
749 | */ | ||
750 | char *kaddr = kmap_atomic(page, KM_USER0); | ||
751 | dump->page = page; | ||
752 | memcpy(dump->data + offset, kaddr + offset, | ||
753 | PAGE_SIZE - offset); | ||
754 | kunmap_atomic(kaddr, KM_USER0); | ||
755 | } | ||
756 | /* Same with put_arg_page(page) in fs/exec.c */ | ||
757 | #ifdef CONFIG_MMU | ||
758 | put_page(page); | ||
759 | #endif | ||
760 | return true; | ||
761 | } | ||