Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only
2 : /*
3 : * Access kernel or user memory without faulting.
4 : */
5 : #include <linux/export.h>
6 : #include <linux/mm.h>
7 : #include <linux/uaccess.h>
8 :
9 0 : bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
10 : size_t size)
11 : {
12 0 : return true;
13 : }
14 :
15 : #define copy_from_kernel_nofault_loop(dst, src, len, type, err_label) \
16 : while (len >= sizeof(type)) { \
17 : __get_kernel_nofault(dst, src, type, err_label); \
18 : dst += sizeof(type); \
19 : src += sizeof(type); \
20 : len -= sizeof(type); \
21 : }
22 :
23 0 : long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
24 : {
25 0 : unsigned long align = 0;
26 :
27 : if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
28 0 : align = (unsigned long)dst | (unsigned long)src;
29 :
30 0 : if (!copy_from_kernel_nofault_allowed(src, size))
31 : return -ERANGE;
32 :
33 0 : pagefault_disable();
34 0 : if (!(align & 7))
35 0 : copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
36 0 : if (!(align & 3))
37 0 : copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
38 0 : if (!(align & 1))
39 0 : copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
40 0 : copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
41 0 : pagefault_enable();
42 0 : return 0;
43 : Efault:
44 : pagefault_enable();
45 : return -EFAULT;
46 : }
47 : EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
48 :
49 : #define copy_to_kernel_nofault_loop(dst, src, len, type, err_label) \
50 : while (len >= sizeof(type)) { \
51 : __put_kernel_nofault(dst, src, type, err_label); \
52 : dst += sizeof(type); \
53 : src += sizeof(type); \
54 : len -= sizeof(type); \
55 : }
56 :
57 0 : long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
58 : {
59 0 : unsigned long align = 0;
60 :
61 : if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
62 0 : align = (unsigned long)dst | (unsigned long)src;
63 :
64 0 : pagefault_disable();
65 0 : if (!(align & 7))
66 0 : copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
67 0 : if (!(align & 3))
68 0 : copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
69 0 : if (!(align & 1))
70 0 : copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
71 0 : copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
72 0 : pagefault_enable();
73 : return 0;
74 : Efault:
75 : pagefault_enable();
76 : return -EFAULT;
77 : }
78 :
79 0 : long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
80 : {
81 0 : const void *src = unsafe_addr;
82 :
83 0 : if (unlikely(count <= 0))
84 : return 0;
85 0 : if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
86 : return -ERANGE;
87 :
88 : pagefault_disable();
89 : do {
90 0 : __get_kernel_nofault(dst, src, u8, Efault);
91 0 : dst++;
92 0 : src++;
93 0 : } while (dst[-1] && src - unsafe_addr < count);
94 0 : pagefault_enable();
95 :
96 0 : dst[-1] = '\0';
97 0 : return src - unsafe_addr;
98 : Efault:
99 : pagefault_enable();
100 : dst[0] = '\0';
101 : return -EFAULT;
102 : }
103 :
104 : /**
105 : * copy_from_user_nofault(): safely attempt to read from a user-space location
106 : * @dst: pointer to the buffer that shall take the data
107 : * @src: address to read from. This must be a user address.
108 : * @size: size of the data chunk
109 : *
110 : * Safely read from user address @src to the buffer at @dst. If a kernel fault
111 : * happens, handle that and return -EFAULT.
112 : */
113 0 : long copy_from_user_nofault(void *dst, const void __user *src, size_t size)
114 : {
115 0 : long ret = -EFAULT;
116 0 : if (access_ok(src, size)) {
117 0 : pagefault_disable();
118 0 : ret = __copy_from_user_inatomic(dst, src, size);
119 : pagefault_enable();
120 : }
121 :
122 0 : if (ret)
123 : return -EFAULT;
124 0 : return 0;
125 : }
126 : EXPORT_SYMBOL_GPL(copy_from_user_nofault);
127 :
128 : /**
129 : * copy_to_user_nofault(): safely attempt to write to a user-space location
130 : * @dst: address to write to
131 : * @src: pointer to the data that shall be written
132 : * @size: size of the data chunk
133 : *
134 : * Safely write to address @dst from the buffer at @src. If a kernel fault
135 : * happens, handle that and return -EFAULT.
136 : */
137 0 : long copy_to_user_nofault(void __user *dst, const void *src, size_t size)
138 : {
139 0 : long ret = -EFAULT;
140 :
141 0 : if (access_ok(dst, size)) {
142 0 : pagefault_disable();
143 0 : ret = __copy_to_user_inatomic(dst, src, size);
144 : pagefault_enable();
145 : }
146 :
147 0 : if (ret)
148 : return -EFAULT;
149 0 : return 0;
150 : }
151 : EXPORT_SYMBOL_GPL(copy_to_user_nofault);
152 :
153 : /**
154 : * strncpy_from_user_nofault: - Copy a NUL terminated string from unsafe user
155 : * address.
156 : * @dst: Destination address, in kernel space. This buffer must be at
157 : * least @count bytes long.
158 : * @unsafe_addr: Unsafe user address.
159 : * @count: Maximum number of bytes to copy, including the trailing NUL.
160 : *
161 : * Copies a NUL-terminated string from unsafe user address to kernel buffer.
162 : *
163 : * On success, returns the length of the string INCLUDING the trailing NUL.
164 : *
165 : * If access fails, returns -EFAULT (some data may have been copied
166 : * and the trailing NUL added).
167 : *
168 : * If @count is smaller than the length of the string, copies @count-1 bytes,
169 : * sets the last byte of @dst buffer to NUL and returns @count.
170 : */
171 0 : long strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
172 : long count)
173 : {
174 : long ret;
175 :
176 0 : if (unlikely(count <= 0))
177 : return 0;
178 :
179 0 : pagefault_disable();
180 0 : ret = strncpy_from_user(dst, unsafe_addr, count);
181 0 : pagefault_enable();
182 :
183 0 : if (ret >= count) {
184 0 : ret = count;
185 0 : dst[ret - 1] = '\0';
186 0 : } else if (ret > 0) {
187 0 : ret++;
188 : }
189 :
190 : return ret;
191 : }
192 :
193 : /**
194 : * strnlen_user_nofault: - Get the size of a user string INCLUDING final NUL.
195 : * @unsafe_addr: The string to measure.
196 : * @count: Maximum count (including NUL)
197 : *
198 : * Get the size of a NUL-terminated string in user space without pagefault.
199 : *
200 : * Returns the size of the string INCLUDING the terminating NUL.
201 : *
202 : * If the string is too long, returns a number larger than @count. User
203 : * has to check the return value against "> count".
204 : * On exception (or invalid count), returns 0.
205 : *
206 : * Unlike strnlen_user, this can be used from IRQ handler etc. because
207 : * it disables pagefaults.
208 : */
209 0 : long strnlen_user_nofault(const void __user *unsafe_addr, long count)
210 : {
211 : int ret;
212 :
213 0 : pagefault_disable();
214 0 : ret = strnlen_user(unsafe_addr, count);
215 0 : pagefault_enable();
216 :
217 0 : return ret;
218 : }
219 :
220 0 : void __copy_overflow(int size, unsigned long count)
221 : {
222 0 : WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
223 0 : }
224 : EXPORT_SYMBOL(__copy_overflow);
|