diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-07-08 13:24:54 +0900 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-07-11 11:05:33 +1000 |
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) kfree(tmp); return retval; } + +/** + * tomoyo_dump_page - Dump a page to buffer. + * + * @bprm: Pointer to "struct linux_binprm". + * @pos: Location to dump. + * @dump: Poiner to "struct tomoyo_page_dump". + * + * Returns true on success, false otherwise. + */ +bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, + struct tomoyo_page_dump *dump) +{ + struct page *page; + /* dump->data is released by tomoyo_finish_execve(). */ + if (!dump->data) { + dump->data = kzalloc(PAGE_SIZE, GFP_NOFS); + if (!dump->data) + return false; + } + /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */ +#ifdef CONFIG_MMU + if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) + return false; +#else + page = bprm->page[pos / PAGE_SIZE]; +#endif + if (page != dump->page) { + const unsigned int offset = pos % PAGE_SIZE; + /* + * Maybe kmap()/kunmap() should be used here. + * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic(). + * So do I. + */ + char *kaddr = kmap_atomic(page, KM_USER0); + dump->page = page; + memcpy(dump->data + offset, kaddr + offset, + PAGE_SIZE - offset); + kunmap_atomic(kaddr, KM_USER0); + } + /* Same with put_arg_page(page) in fs/exec.c */ +#ifdef CONFIG_MMU + put_page(page); +#endif + return true; +} |