forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
uaccess: Add strict non-pagefault kernel-space read function
Add two new probe_kernel_read_strict() and strncpy_from_unsafe_strict() helpers which by default alias to the __probe_kernel_read() and the __strncpy_from_unsafe(), respectively, but can be overridden by archs which have non-overlapping address ranges for kernel space and user space in order to bail out with -EFAULT when attempting to probe user memory including non-canonical user access addresses [0]: 4-level page tables: user-space mem: 0x0000000000000000 - 0x00007fffffffffff non-canonical: 0x0000800000000000 - 0xffff7fffffffffff 5-level page tables: user-space mem: 0x0000000000000000 - 0x00ffffffffffffff non-canonical: 0x0100000000000000 - 0xfeffffffffffffff The idea is that these helpers are complementary to the probe_user_read() and strncpy_from_unsafe_user() which probe user-only memory. Both added helpers here do the same, but for kernel-only addresses. Both set of helpers are going to be used for BPF tracing. They also explicitly avoid throwing the splat for non-canonical user addresses from 00c4237 ("x86-64: add warning for non-canonical user access address dereferences"). For compat, the current probe_kernel_read() and strncpy_from_unsafe() are left as-is. [0] Documentation/x86/x86_64/mm.txt Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/bpf/eefeefd769aa5a013531f491a71f0936779e916b.1572649915.git.daniel@iogearbox.net
- Loading branch information
Showing
4 changed files
with
72 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
|
||
#include <linux/uaccess.h> | ||
#include <linux/kernel.h> | ||
|
||
#ifdef CONFIG_X86_64 | ||
static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits) | ||
{ | ||
return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); | ||
} | ||
|
||
static __always_inline bool invalid_probe_range(u64 vaddr) | ||
{ | ||
/* | ||
* Range covering the highest possible canonical userspace address | ||
* as well as non-canonical address range. For the canonical range | ||
* we also need to include the userspace guard page. | ||
*/ | ||
return vaddr < TASK_SIZE_MAX + PAGE_SIZE || | ||
canonical_address(vaddr, boot_cpu_data.x86_virt_bits) != vaddr; | ||
} | ||
#else | ||
static __always_inline bool invalid_probe_range(u64 vaddr) | ||
{ | ||
return vaddr < TASK_SIZE_MAX; | ||
} | ||
#endif | ||
|
||
long probe_kernel_read_strict(void *dst, const void *src, size_t size) | ||
{ | ||
if (unlikely(invalid_probe_range((unsigned long)src))) | ||
return -EFAULT; | ||
|
||
return __probe_kernel_read(dst, src, size); | ||
} | ||
|
||
long strncpy_from_unsafe_strict(char *dst, const void *unsafe_addr, long count) | ||
{ | ||
if (unlikely(invalid_probe_range((unsigned long)unsafe_addr))) | ||
return -EFAULT; | ||
|
||
return __strncpy_from_unsafe(dst, unsafe_addr, count); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters