TOMOYO: Allow using argv[]/envp[] of execve() as conditions.
[deliverable/linux.git] / security / tomoyo / domain.c
index 0f02c7852090f3fbc9f65ec6541d82295be78ece..565249c42e39817d5069898a825c8e536f2853bc 100644 (file)
@@ -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;
+}
This page took 0.024145 seconds and 5 git commands to generate.