@@ -11,6 +11,81 @@ bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size)
11
11
return true;
12
12
}
13
13
14
+ #ifdef HAVE_GET_KERNEL_NOFAULT
15
+
16
+ #define probe_kernel_read_loop (dst , src , len , type , err_label ) \
17
+ while (len >= sizeof(type)) { \
18
+ __get_kernel_nofault(dst, src, type, err_label); \
19
+ dst += sizeof(type); \
20
+ src += sizeof(type); \
21
+ len -= sizeof(type); \
22
+ }
23
+
24
+ long probe_kernel_read (void * dst , const void * src , size_t size )
25
+ {
26
+ if (!probe_kernel_read_allowed (src , size ))
27
+ return - EFAULT ;
28
+
29
+ pagefault_disable ();
30
+ probe_kernel_read_loop (dst , src , size , u64 , Efault );
31
+ probe_kernel_read_loop (dst , src , size , u32 , Efault );
32
+ probe_kernel_read_loop (dst , src , size , u16 , Efault );
33
+ probe_kernel_read_loop (dst , src , size , u8 , Efault );
34
+ pagefault_enable ();
35
+ return 0 ;
36
+ Efault :
37
+ pagefault_enable ();
38
+ return - EFAULT ;
39
+ }
40
+ EXPORT_SYMBOL_GPL (probe_kernel_read );
41
+
42
+ #define probe_kernel_write_loop (dst , src , len , type , err_label ) \
43
+ while (len >= sizeof(type)) { \
44
+ __put_kernel_nofault(dst, src, type, err_label); \
45
+ dst += sizeof(type); \
46
+ src += sizeof(type); \
47
+ len -= sizeof(type); \
48
+ }
49
+
50
+ long probe_kernel_write (void * dst , const void * src , size_t size )
51
+ {
52
+ pagefault_disable ();
53
+ probe_kernel_write_loop (dst , src , size , u64 , Efault );
54
+ probe_kernel_write_loop (dst , src , size , u32 , Efault );
55
+ probe_kernel_write_loop (dst , src , size , u16 , Efault );
56
+ probe_kernel_write_loop (dst , src , size , u8 , Efault );
57
+ pagefault_enable ();
58
+ return 0 ;
59
+ Efault :
60
+ pagefault_enable ();
61
+ return - EFAULT ;
62
+ }
63
+
64
+ long strncpy_from_kernel_nofault (char * dst , const void * unsafe_addr , long count )
65
+ {
66
+ const void * src = unsafe_addr ;
67
+
68
+ if (unlikely (count <= 0 ))
69
+ return 0 ;
70
+ if (!probe_kernel_read_allowed (unsafe_addr , count ))
71
+ return - EFAULT ;
72
+
73
+ pagefault_disable ();
74
+ do {
75
+ __get_kernel_nofault (dst , src , u8 , Efault );
76
+ dst ++ ;
77
+ src ++ ;
78
+ } while (dst [-1 ] && src - unsafe_addr < count );
79
+ pagefault_enable ();
80
+
81
+ dst [-1 ] = '\0' ;
82
+ return src - unsafe_addr ;
83
+ Efault :
84
+ pagefault_enable ();
85
+ dst [-1 ] = '\0' ;
86
+ return - EFAULT ;
87
+ }
88
+ #else /* HAVE_GET_KERNEL_NOFAULT */
14
89
/**
15
90
* probe_kernel_read(): safely attempt to read from kernel-space
16
91
* @dst: pointer to the buffer that shall take the data
@@ -113,6 +188,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
113
188
114
189
return ret ? - EFAULT : src - unsafe_addr ;
115
190
}
191
+ #endif /* HAVE_GET_KERNEL_NOFAULT */
116
192
117
193
/**
118
194
* probe_user_read(): safely attempt to read from a user-space location
0 commit comments