Branch data 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 : 0 : static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits) 8 : : { 9 : 0 : return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); 10 : : } 11 : : 12 : 0 : static __always_inline bool invalid_probe_range(u64 vaddr) 13 : : { 14 : : /* 15 : : * Range covering the highest possible canonical userspace address 16 : : * as well as non-canonical address range. For the canonical range 17 : : * we also need to include the userspace guard page. 18 : : */ 19 [ # # # # ]: 0 : return vaddr < TASK_SIZE_MAX + PAGE_SIZE || 20 [ # # # # ]: 0 : canonical_address(vaddr, boot_cpu_data.x86_virt_bits) != vaddr; 21 : : } 22 : : #else 23 : : static __always_inline bool invalid_probe_range(u64 vaddr) 24 : : { 25 : : return vaddr < TASK_SIZE_MAX; 26 : : } 27 : : #endif 28 : : 29 : 0 : long probe_kernel_read_strict(void *dst, const void *src, size_t size) 30 : : { 31 [ # # # # : 0 : if (unlikely(invalid_probe_range((unsigned long)src))) # ] 32 : : return -EFAULT; 33 : : 34 : 0 : return __probe_kernel_read(dst, src, size); 35 : : } 36 : : 37 : 0 : long strncpy_from_unsafe_strict(char *dst, const void *unsafe_addr, long count) 38 : : { 39 [ # # # # : 0 : if (unlikely(invalid_probe_range((unsigned long)unsafe_addr))) # ] 40 : : return -EFAULT; 41 : : 42 : 0 : return __strncpy_from_unsafe(dst, unsafe_addr, count); 43 : : }