/* * Kernel module for testing copy_to/from_user infrastructure. * * Copyright 2013 Google Inc. All Rights Reserved * * Authors: * Kees Cook <keescook@chromium.org> * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/mman.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/vmalloc.h> #define test(condition, msg) \ ({ \ int cond = (condition); \ if (cond) \ pr_warn("%s\n", msg); \ cond; \ }) static int __init test_user_copy_init(void) { int ret = 0; char *kmem; char __user *usermem; char *bad_usermem; unsigned long user_addr; unsigned long value = 0x5A; kmem = kmalloc(PAGE_SIZE * 2, GFP_KERNEL); if (!kmem) return -ENOMEM; user_addr = vm_mmap(NULL, 0, PAGE_SIZE * 2, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0); if (user_addr >= (unsigned long)(TASK_SIZE)) { pr_warn("Failed to allocate user memory\n"); kfree(kmem); return -ENOMEM; } usermem = (char __user *)user_addr; bad_usermem = (char *)user_addr; /* Legitimate usage: none of these should fail. */ ret |= test(copy_from_user(kmem, usermem, PAGE_SIZE), "legitimate copy_from_user failed"); ret |= test(copy_to_user(usermem, kmem, PAGE_SIZE), "legitimate copy_to_user failed"); ret |= test(get_user(value, (unsigned long __user *)usermem), "legitimate get_user failed"); ret |= test(put_user(value, (unsigned long __user *)usermem), "legitimate put_user failed"); /* Invalid usage: none of these should succeed. */ ret |= test(!copy_from_user(kmem, (char __user *)(kmem + PAGE_SIZE), PAGE_SIZE), "illegal all-kernel copy_from_user passed"); ret |= test(!copy_from_user(bad_usermem, (char __user *)kmem, PAGE_SIZE), "illegal reversed copy_from_user passed"); ret |= test(!copy_to_user((char __user *)kmem, kmem + PAGE_SIZE, PAGE_SIZE), "illegal all-kernel copy_to_user passed"); ret |= test(!copy_to_user((char __user *)kmem, bad_usermem, PAGE_SIZE), "illegal reversed copy_to_user passed"); ret |= test(!get_user(value, (unsigned long __user *)kmem), "illegal get_user passed"); ret |= test(!put_user(value, (unsigned long __user *)kmem), "illegal put_user passed"); vm_munmap(user_addr, PAGE_SIZE * 2); kfree(kmem); if (ret == 0) { pr_info("tests passed.\n"); return 0; } return -EINVAL; } module_init(test_user_copy_init); static void __exit test_user_copy_exit(void) { pr_info("unloaded.\n"); } module_exit(test_user_copy_exit); MODULE_AUTHOR("Kees Cook <keescook@chromium.org>"); MODULE_LICENSE("GPL"); vicetree/bindings/pci?h=nds-private-remove'>pci</a>/<a href='/cgit.cgi/linux/net-next.git/diff/Documentation/devicetree/bindings/pci/xilinx-pcie.txt?h=nds-private-remove'>xilinx-pcie.txt</a></div><div class='content'><div class='cgit-panel'><b>diff options</b><form method='get'><input type='hidden' name='h' value='nds-private-remove'/><table><tr><td colspan='2'/></tr><tr><td class='label'>context:</td><td class='ctrl'><select name='context' onchange='this.form.submit();'><option value='1'>1</option><option value='2'>2</option><option value='3' selected='selected'>3</option><option value='4'>4</option><option value='5'>5</option><option value='6'>6</option><option value='7'>7</option><option value='8'>8</option><option value='9'>9</option><option value='10'>10</option><option value='15'>15</option><option value='20'>20</option><option value='25'>25</option><option value='30'>30</option><option value='35'>35</option><option value='40'>40</option></select></td></tr><tr><td class='label'>space:</td><td class='ctrl'><select name='ignorews' onchange='this.form.submit();'><option value='0' selected='selected'>include</option><option value='1'>ignore</option></select></td></tr><tr><td class='label'>mode:</td><td class='ctrl'><select name='dt' onchange='this.form.submit();'><option value='0' selected='selected'>unified</option><option value='1'>ssdiff</option><option value='2'>stat only</option></select></td></tr><tr><td/><td class='ctrl'><noscript><input type='submit' value='reload'/></noscript></td></tr></table></form></div><div class='diffstat-header'><a href='/cgit.cgi/linux/net-next.git/diff/?h=nds-private-remove'>Diffstat</a> (limited to 'Documentation/devicetree/bindings/pci/xilinx-pcie.txt')</div><table summary='diffstat' class='diffstat'>