Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only 2 : 3 : #include <linux/uaccess.h> 4 : #include <linux/kernel.h> 5 : 6 : #ifdef CONFIG_X86_64 7 98 : static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits) 8 : { 9 98 : return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); 10 : } 11 : 12 98 : bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) 13 : { 14 98 : unsigned long vaddr = (unsigned long)unsafe_src; 15 : 16 : /* 17 : * Range covering the highest possible canonical userspace address 18 : * as well as non-canonical address range. For the canonical range 19 : * we also need to include the userspace guard page. 20 : */ 21 98 : return vaddr >= TASK_SIZE_MAX + PAGE_SIZE && 22 98 : canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr; 23 : } 24 : #else 25 : bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) 26 : { 27 : return (unsigned long)unsafe_src >= TASK_SIZE_MAX; 28 : } 29 : #endif