Branch data Line data Source code
1 : : /*
2 : : * Access kernel memory without faulting.
3 : : */
4 : : #include <linux/export.h>
5 : : #include <linux/mm.h>
6 : : #include <linux/uaccess.h>
7 : :
8 : : /**
9 : : * probe_kernel_read(): safely attempt to read from a location
10 : : * @dst: pointer to the buffer that shall take the data
11 : : * @src: address to read from
12 : : * @size: size of the data chunk
13 : : *
14 : : * Safely read from address @src to the buffer at @dst. If a kernel fault
15 : : * happens, handle that and return -EFAULT.
16 : : */
17 : :
18 : : long __weak probe_kernel_read(void *dst, const void *src, size_t size)
19 : : __attribute__((alias("__probe_kernel_read")));
20 : :
21 : 0 : long __probe_kernel_read(void *dst, const void *src, size_t size)
22 : : {
23 : : long ret;
24 : 0 : mm_segment_t old_fs = get_fs();
25 : :
26 : : set_fs(KERNEL_DS);
27 : : pagefault_disable();
28 : 0 : ret = __copy_from_user_inatomic(dst,
29 : : (__force const void __user *)src, size);
30 : : pagefault_enable();
31 : : set_fs(old_fs);
32 : :
33 [ # # ]: 0 : return ret ? -EFAULT : 0;
34 : : }
35 : : EXPORT_SYMBOL_GPL(probe_kernel_read);
36 : :
37 : : /**
38 : : * probe_kernel_write(): safely attempt to write to a location
39 : : * @dst: address to write to
40 : : * @src: pointer to the data that shall be written
41 : : * @size: size of the data chunk
42 : : *
43 : : * Safely write to address @dst from the buffer at @src. If a kernel fault
44 : : * happens, handle that and return -EFAULT.
45 : : */
46 : : long __weak probe_kernel_write(void *dst, const void *src, size_t size)
47 : : __attribute__((alias("__probe_kernel_write")));
48 : :
49 : 0 : long __probe_kernel_write(void *dst, const void *src, size_t size)
50 : : {
51 : : long ret;
52 : 0 : mm_segment_t old_fs = get_fs();
53 : :
54 : : set_fs(KERNEL_DS);
55 : : pagefault_disable();
56 : 0 : ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
57 : : pagefault_enable();
58 : : set_fs(old_fs);
59 : :
60 [ # # ]: 0 : return ret ? -EFAULT : 0;
61 : : }
62 : : EXPORT_SYMBOL_GPL(probe_kernel_write);
|