GNU Linux-libre 4.4.285-gnu1
[releases.git] / mm / maccess.c
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 static __always_inline long
9 probe_read_common(void *dst, const void __user *src, size_t size)
10 {
11         long ret;
12
13         pagefault_disable();
14         ret = __copy_from_user_inatomic(dst, src, size);
15         pagefault_enable();
16
17         return ret ? -EFAULT : 0;
18 }
19
20 static __always_inline long
21 probe_write_common(void __user *dst, const void *src, size_t size)
22 {
23         long ret;
24
25         pagefault_disable();
26         ret = __copy_to_user_inatomic(dst, src, size);
27         pagefault_enable();
28
29         return ret ? -EFAULT : 0;
30 }
31
32 /**
33  * probe_kernel_read(): safely attempt to read from a kernel-space location
34  * @dst: pointer to the buffer that shall take the data
35  * @src: address to read from
36  * @size: size of the data chunk
37  *
38  * Safely read from address @src to the buffer at @dst.  If a kernel fault
39  * happens, handle that and return -EFAULT.
40  *
41  * We ensure that the copy_from_user is executed in atomic context so that
42  * do_page_fault() doesn't attempt to take mmap_sem.  This makes
43  * probe_kernel_read() suitable for use within regions where the caller
44  * already holds mmap_sem, or other locks which nest inside mmap_sem.
45  */
46
47 long __weak probe_kernel_read(void *dst, const void *src, size_t size)
48     __attribute__((alias("__probe_kernel_read")));
49
50 long __probe_kernel_read(void *dst, const void *src, size_t size)
51 {
52         long ret;
53         mm_segment_t old_fs = get_fs();
54
55         set_fs(KERNEL_DS);
56         ret = probe_read_common(dst, (__force const void __user *)src, size);
57         set_fs(old_fs);
58
59         return ret;
60 }
61 EXPORT_SYMBOL_GPL(probe_kernel_read);
62
63 /**
64  * probe_user_read(): safely attempt to read from a user-space location
65  * @dst: pointer to the buffer that shall take the data
66  * @src: address to read from. This must be a user address.
67  * @size: size of the data chunk
68  *
69  * Safely read from user address @src to the buffer at @dst. If a kernel fault
70  * happens, handle that and return -EFAULT.
71  */
72
73 long __weak probe_user_read(void *dst, const void __user *src, size_t size)
74     __attribute__((alias("__probe_user_read")));
75
76 long __probe_user_read(void *dst, const void __user *src, size_t size)
77 {
78         long ret = -EFAULT;
79         mm_segment_t old_fs = get_fs();
80
81         set_fs(USER_DS);
82         if (access_ok(VERIFY_READ, src, size))
83                 ret = probe_read_common(dst, src, size);
84         set_fs(old_fs);
85
86         return ret;
87 }
88 EXPORT_SYMBOL_GPL(probe_user_read);
89
90 /**
91  * probe_kernel_write(): safely attempt to write to a location
92  * @dst: address to write to
93  * @src: pointer to the data that shall be written
94  * @size: size of the data chunk
95  *
96  * Safely write to address @dst from the buffer at @src.  If a kernel fault
97  * happens, handle that and return -EFAULT.
98  */
99
100 long __weak probe_kernel_write(void *dst, const void *src, size_t size)
101     __attribute__((alias("__probe_kernel_write")));
102
103 long __probe_kernel_write(void *dst, const void *src, size_t size)
104 {
105         long ret;
106         mm_segment_t old_fs = get_fs();
107
108         set_fs(KERNEL_DS);
109         ret = probe_write_common((__force void __user *)dst, src, size);
110         set_fs(old_fs);
111
112         return ret;
113 }
114 EXPORT_SYMBOL_GPL(probe_kernel_write);
115
116 /**
117  * probe_user_write(): safely attempt to write to a user-space location
118  * @dst: address to write to
119  * @src: pointer to the data that shall be written
120  * @size: size of the data chunk
121  *
122  * Safely write to address @dst from the buffer at @src.  If a kernel fault
123  * happens, handle that and return -EFAULT.
124  */
125
126 long __weak probe_user_write(void __user *dst, const void *src, size_t size)
127     __attribute__((alias("__probe_user_write")));
128
129 long __probe_user_write(void __user *dst, const void *src, size_t size)
130 {
131         long ret = -EFAULT;
132         mm_segment_t old_fs = get_fs();
133
134         set_fs(USER_DS);
135         if (access_ok(VERIFY_WRITE, dst, size))
136                 ret = probe_write_common(dst, src, size);
137         set_fs(old_fs);
138
139         return ret;
140 }
141 EXPORT_SYMBOL_GPL(probe_user_write);
142
143 /**
144  * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
145  * @dst:   Destination address, in kernel space.  This buffer must be at
146  *         least @count bytes long.
147  * @src:   Unsafe address.
148  * @count: Maximum number of bytes to copy, including the trailing NUL.
149  *
150  * Copies a NUL-terminated string from unsafe address to kernel buffer.
151  *
152  * On success, returns the length of the string INCLUDING the trailing NUL.
153  *
154  * If access fails, returns -EFAULT (some data may have been copied
155  * and the trailing NUL added).
156  *
157  * If @count is smaller than the length of the string, copies @count-1 bytes,
158  * sets the last byte of @dst buffer to NUL and returns @count.
159  */
160 long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
161 {
162         mm_segment_t old_fs = get_fs();
163         const void *src = unsafe_addr;
164         long ret;
165
166         if (unlikely(count <= 0))
167                 return 0;
168
169         set_fs(KERNEL_DS);
170         pagefault_disable();
171
172         do {
173                 ret = __copy_from_user_inatomic(dst++,
174                                                 (const void __user __force *)src++, 1);
175         } while (dst[-1] && ret == 0 && src - unsafe_addr < count);
176
177         dst[-1] = '\0';
178         pagefault_enable();
179         set_fs(old_fs);
180
181         return ret ? -EFAULT : src - unsafe_addr;
182 }
183
184 /**
185  * strncpy_from_unsafe_user: - Copy a NUL terminated string from unsafe user
186  *                              address.
187  * @dst:   Destination address, in kernel space.  This buffer must be at
188  *         least @count bytes long.
189  * @unsafe_addr: Unsafe user address.
190  * @count: Maximum number of bytes to copy, including the trailing NUL.
191  *
192  * Copies a NUL-terminated string from unsafe user address to kernel buffer.
193  *
194  * On success, returns the length of the string INCLUDING the trailing NUL.
195  *
196  * If access fails, returns -EFAULT (some data may have been copied
197  * and the trailing NUL added).
198  *
199  * If @count is smaller than the length of the string, copies @count-1 bytes,
200  * sets the last byte of @dst buffer to NUL and returns @count.
201  */
202 long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr,
203                               long count)
204 {
205         mm_segment_t old_fs = get_fs();
206         long ret;
207
208         if (unlikely(count <= 0))
209                 return 0;
210
211         set_fs(USER_DS);
212         pagefault_disable();
213         ret = strncpy_from_user(dst, unsafe_addr, count);
214         pagefault_enable();
215         set_fs(old_fs);
216
217         if (ret >= count) {
218                 ret = count;
219                 dst[ret - 1] = '\0';
220         } else if (ret > 0) {
221                 ret++;
222         }
223
224         return ret;
225 }
226
227 /**
228  * strnlen_unsafe_user: - Get the size of a user string INCLUDING final NUL.
229  * @unsafe_addr: The string to measure.
230  * @count: Maximum count (including NUL)
231  *
232  * Get the size of a NUL-terminated string in user space without pagefault.
233  *
234  * Returns the size of the string INCLUDING the terminating NUL.
235  *
236  * If the string is too long, returns a number larger than @count. User
237  * has to check the return value against "> count".
238  * On exception (or invalid count), returns 0.
239  *
240  * Unlike strnlen_user, this can be used from IRQ handler etc. because
241  * it disables pagefaults.
242  */
243 long strnlen_unsafe_user(const void __user *unsafe_addr, long count)
244 {
245         mm_segment_t old_fs = get_fs();
246         int ret;
247
248         set_fs(USER_DS);
249         pagefault_disable();
250         ret = strnlen_user(unsafe_addr, count);
251         pagefault_enable();
252         set_fs(old_fs);
253
254         return ret;
255 }