blob: 88ab30c054a9776a4790520f594cad10403fbcfe [file] [log] [blame]
Thomas Gleixner457c8992019-05-19 13:08:55 +01001// SPDX-License-Identifier: GPL-2.0-only
Ingo Molnarc33fa9f2008-04-17 20:05:36 +02002/*
Christoph Hellwig3f0acb12020-06-08 21:34:11 -07003 * Access kernel or user memory without faulting.
Ingo Molnarc33fa9f2008-04-17 20:05:36 +02004 */
Paul Gortmakerb95f1b312011-10-16 02:01:52 -04005#include <linux/export.h>
Ingo Molnarc33fa9f2008-04-17 20:05:36 +02006#include <linux/mm.h>
David Howells7c7fcf72010-10-27 17:29:01 +01007#include <linux/uaccess.h>
Ingo Molnarc33fa9f2008-04-17 20:05:36 +02008
Masami Hiramatsu3d708182019-05-15 14:38:18 +09009static __always_inline long
10probe_read_common(void *dst, const void __user *src, size_t size)
11{
12 long ret;
13
14 pagefault_disable();
15 ret = __copy_from_user_inatomic(dst, src, size);
16 pagefault_enable();
17
18 return ret ? -EFAULT : 0;
19}
20
Daniel Borkmann1d1585c2019-11-02 00:17:56 +010021static __always_inline long
22probe_write_common(void __user *dst, const void *src, size_t size)
23{
24 long ret;
25
26 pagefault_disable();
27 ret = __copy_to_user_inatomic(dst, src, size);
28 pagefault_enable();
29
30 return ret ? -EFAULT : 0;
31}
32
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020033/**
Christoph Hellwig4f6de122020-06-08 21:34:07 -070034 * probe_kernel_read(): safely attempt to read from any location
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020035 * @dst: pointer to the buffer that shall take the data
36 * @src: address to read from
37 * @size: size of the data chunk
38 *
Christoph Hellwig4f6de122020-06-08 21:34:07 -070039 * Same as probe_kernel_read_strict() except that for architectures with
40 * not fully separated user and kernel address spaces this function also works
41 * for user address tanges.
42 *
43 * DO NOT USE THIS FUNCTION - it is broken on architectures with entirely
44 * separate kernel and user address spaces, and also a bad idea otherwise.
45 */
46long __weak probe_kernel_read(void *dst, const void *src, size_t size)
47 __attribute__((alias("__probe_kernel_read")));
48
49/**
50 * probe_kernel_read_strict(): safely attempt to read from kernel-space
51 * @dst: pointer to the buffer that shall take the data
52 * @src: address to read from
53 * @size: size of the data chunk
54 *
55 * Safely read from kernel address @src to the buffer at @dst. If a kernel
56 * fault happens, handle that and return -EFAULT.
Andrew Morton0ab32b62015-11-05 18:46:03 -080057 *
58 * We ensure that the copy_from_user is executed in atomic context so that
Michel Lespinassec1e8d7c2020-06-08 21:33:54 -070059 * do_page_fault() doesn't attempt to take mmap_lock. This makes
Andrew Morton0ab32b62015-11-05 18:46:03 -080060 * probe_kernel_read() suitable for use within regions where the caller
Michel Lespinassec1e8d7c2020-06-08 21:33:54 -070061 * already holds mmap_lock, or other locks which nest inside mmap_lock.
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020062 */
Jason Wessel6144a852010-01-07 11:58:36 -060063
Daniel Borkmann75a1a602019-11-02 00:17:57 +010064long __weak probe_kernel_read_strict(void *dst, const void *src, size_t size)
65 __attribute__((alias("__probe_kernel_read")));
66
Steven Rostedtf29c5042011-05-19 14:35:33 -040067long __probe_kernel_read(void *dst, const void *src, size_t size)
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020068{
69 long ret;
Jason Wesselb4b8ac52008-02-20 13:33:38 -060070 mm_segment_t old_fs = get_fs();
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020071
Jason Wesselb4b8ac52008-02-20 13:33:38 -060072 set_fs(KERNEL_DS);
Masami Hiramatsu3d708182019-05-15 14:38:18 +090073 ret = probe_read_common(dst, (__force const void __user *)src, size);
Jason Wesselb4b8ac52008-02-20 13:33:38 -060074 set_fs(old_fs);
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020075
Masami Hiramatsu3d708182019-05-15 14:38:18 +090076 return ret;
Ingo Molnarc33fa9f2008-04-17 20:05:36 +020077}
78EXPORT_SYMBOL_GPL(probe_kernel_read);
79
80/**
Masami Hiramatsu3d708182019-05-15 14:38:18 +090081 * probe_user_read(): safely attempt to read from a user-space location
82 * @dst: pointer to the buffer that shall take the data
83 * @src: address to read from. This must be a user address.
84 * @size: size of the data chunk
85 *
86 * Safely read from user address @src to the buffer at @dst. If a kernel fault
87 * happens, handle that and return -EFAULT.
88 */
Christoph Hellwig48c49c02020-06-08 21:34:01 -070089long probe_user_read(void *dst, const void __user *src, size_t size)
Masami Hiramatsu3d708182019-05-15 14:38:18 +090090{
91 long ret = -EFAULT;
92 mm_segment_t old_fs = get_fs();
93
94 set_fs(USER_DS);
95 if (access_ok(src, size))
96 ret = probe_read_common(dst, src, size);
97 set_fs(old_fs);
98
99 return ret;
100}
101EXPORT_SYMBOL_GPL(probe_user_read);
102
103/**
Ingo Molnarc33fa9f2008-04-17 20:05:36 +0200104 * probe_kernel_write(): safely attempt to write to a location
105 * @dst: address to write to
106 * @src: pointer to the data that shall be written
107 * @size: size of the data chunk
108 *
109 * Safely write to address @dst from the buffer at @src. If a kernel fault
110 * happens, handle that and return -EFAULT.
111 */
Christoph Hellwig48c49c02020-06-08 21:34:01 -0700112long probe_kernel_write(void *dst, const void *src, size_t size)
Ingo Molnarc33fa9f2008-04-17 20:05:36 +0200113{
114 long ret;
Jason Wesselb4b8ac52008-02-20 13:33:38 -0600115 mm_segment_t old_fs = get_fs();
Ingo Molnarc33fa9f2008-04-17 20:05:36 +0200116
Jason Wesselb4b8ac52008-02-20 13:33:38 -0600117 set_fs(KERNEL_DS);
Daniel Borkmann1d1585c2019-11-02 00:17:56 +0100118 ret = probe_write_common((__force void __user *)dst, src, size);
Jason Wesselb4b8ac52008-02-20 13:33:38 -0600119 set_fs(old_fs);
Ingo Molnarc33fa9f2008-04-17 20:05:36 +0200120
Daniel Borkmann1d1585c2019-11-02 00:17:56 +0100121 return ret;
Ingo Molnarc33fa9f2008-04-17 20:05:36 +0200122}
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700123
Daniel Borkmann1d1585c2019-11-02 00:17:56 +0100124/**
125 * probe_user_write(): safely attempt to write to a user-space location
126 * @dst: address to write to
127 * @src: pointer to the data that shall be written
128 * @size: size of the data chunk
129 *
130 * Safely write to address @dst from the buffer at @src. If a kernel fault
131 * happens, handle that and return -EFAULT.
132 */
Christoph Hellwig48c49c02020-06-08 21:34:01 -0700133long probe_user_write(void __user *dst, const void *src, size_t size)
Daniel Borkmann1d1585c2019-11-02 00:17:56 +0100134{
135 long ret = -EFAULT;
136 mm_segment_t old_fs = get_fs();
137
138 set_fs(USER_DS);
139 if (access_ok(dst, size))
140 ret = probe_write_common(dst, src, size);
141 set_fs(old_fs);
142
143 return ret;
144}
145EXPORT_SYMBOL_GPL(probe_user_write);
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900146
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700147/**
148 * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
149 * @dst: Destination address, in kernel space. This buffer must be at
150 * least @count bytes long.
Mike Rapoportf144c392018-02-06 15:42:16 -0800151 * @unsafe_addr: Unsafe address.
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700152 * @count: Maximum number of bytes to copy, including the trailing NUL.
153 *
154 * Copies a NUL-terminated string from unsafe address to kernel buffer.
155 *
156 * On success, returns the length of the string INCLUDING the trailing NUL.
157 *
158 * If access fails, returns -EFAULT (some data may have been copied
159 * and the trailing NUL added).
160 *
161 * If @count is smaller than the length of the string, copies @count-1 bytes,
162 * sets the last byte of @dst buffer to NUL and returns @count.
Daniel Borkmann75a1a602019-11-02 00:17:57 +0100163 *
Christoph Hellwigc4cb1642020-06-08 21:34:17 -0700164 * Same as strncpy_from_kernel_nofault() except that for architectures with
Christoph Hellwig4f6de122020-06-08 21:34:07 -0700165 * not fully separated user and kernel address spaces this function also works
166 * for user address tanges.
167 *
168 * DO NOT USE THIS FUNCTION - it is broken on architectures with entirely
169 * separate kernel and user address spaces, and also a bad idea otherwise.
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700170 */
Daniel Borkmann75a1a602019-11-02 00:17:57 +0100171long __weak strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
172 __attribute__((alias("__strncpy_from_unsafe")));
173
Christoph Hellwig4f6de122020-06-08 21:34:07 -0700174/**
Christoph Hellwigc4cb1642020-06-08 21:34:17 -0700175 * strncpy_from_kernel_nofault: - Copy a NUL terminated string from unsafe
Christoph Hellwig4f6de122020-06-08 21:34:07 -0700176 * address.
177 * @dst: Destination address, in kernel space. This buffer must be at
178 * least @count bytes long.
179 * @unsafe_addr: Unsafe address.
180 * @count: Maximum number of bytes to copy, including the trailing NUL.
181 *
182 * Copies a NUL-terminated string from unsafe address to kernel buffer.
183 *
184 * On success, returns the length of the string INCLUDING the trailing NUL.
185 *
186 * If access fails, returns -EFAULT (some data may have been copied
187 * and the trailing NUL added).
188 *
189 * If @count is smaller than the length of the string, copies @count-1 bytes,
190 * sets the last byte of @dst buffer to NUL and returns @count.
191 */
Christoph Hellwigc4cb1642020-06-08 21:34:17 -0700192long __weak strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr,
Daniel Borkmann75a1a602019-11-02 00:17:57 +0100193 long count)
194 __attribute__((alias("__strncpy_from_unsafe")));
195
196long __strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700197{
198 mm_segment_t old_fs = get_fs();
199 const void *src = unsafe_addr;
200 long ret;
201
202 if (unlikely(count <= 0))
203 return 0;
204
205 set_fs(KERNEL_DS);
206 pagefault_disable();
207
208 do {
Linus Torvaldsbd28b142016-05-22 17:21:27 -0700209 ret = __get_user(*dst++, (const char __user __force *)src++);
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700210 } while (dst[-1] && ret == 0 && src - unsafe_addr < count);
211
212 dst[-1] = '\0';
213 pagefault_enable();
214 set_fs(old_fs);
215
Rasmus Villemoes9dd861d2015-11-05 18:50:11 -0800216 return ret ? -EFAULT : src - unsafe_addr;
Alexei Starovoitovdbb7ee02015-08-31 08:57:10 -0700217}
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900218
219/**
Christoph Hellwigbd88bb52020-06-08 21:34:14 -0700220 * strncpy_from_user_nofault: - Copy a NUL terminated string from unsafe user
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900221 * address.
222 * @dst: Destination address, in kernel space. This buffer must be at
223 * least @count bytes long.
224 * @unsafe_addr: Unsafe user address.
225 * @count: Maximum number of bytes to copy, including the trailing NUL.
226 *
227 * Copies a NUL-terminated string from unsafe user address to kernel buffer.
228 *
229 * On success, returns the length of the string INCLUDING the trailing NUL.
230 *
231 * If access fails, returns -EFAULT (some data may have been copied
232 * and the trailing NUL added).
233 *
234 * If @count is smaller than the length of the string, copies @count-1 bytes,
235 * sets the last byte of @dst buffer to NUL and returns @count.
236 */
Christoph Hellwigbd88bb52020-06-08 21:34:14 -0700237long strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900238 long count)
239{
240 mm_segment_t old_fs = get_fs();
241 long ret;
242
243 if (unlikely(count <= 0))
244 return 0;
245
246 set_fs(USER_DS);
247 pagefault_disable();
248 ret = strncpy_from_user(dst, unsafe_addr, count);
249 pagefault_enable();
250 set_fs(old_fs);
251
252 if (ret >= count) {
253 ret = count;
254 dst[ret - 1] = '\0';
255 } else if (ret > 0) {
256 ret++;
257 }
258
259 return ret;
260}
261
262/**
Christoph Hellwig02dddb12020-06-08 21:34:20 -0700263 * strnlen_user_nofault: - Get the size of a user string INCLUDING final NUL.
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900264 * @unsafe_addr: The string to measure.
265 * @count: Maximum count (including NUL)
266 *
267 * Get the size of a NUL-terminated string in user space without pagefault.
268 *
269 * Returns the size of the string INCLUDING the terminating NUL.
270 *
271 * If the string is too long, returns a number larger than @count. User
272 * has to check the return value against "> count".
273 * On exception (or invalid count), returns 0.
274 *
275 * Unlike strnlen_user, this can be used from IRQ handler etc. because
276 * it disables pagefaults.
277 */
Christoph Hellwig02dddb12020-06-08 21:34:20 -0700278long strnlen_user_nofault(const void __user *unsafe_addr, long count)
Masami Hiramatsu3d708182019-05-15 14:38:18 +0900279{
280 mm_segment_t old_fs = get_fs();
281 int ret;
282
283 set_fs(USER_DS);
284 pagefault_disable();
285 ret = strnlen_user(unsafe_addr, count);
286 pagefault_enable();
287 set_fs(old_fs);
288
289 return ret;
290}