1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __ASM_GENERIC_UACCESS_H 3 #define __ASM_GENERIC_UACCESS_H 4 5 /* 6 * User space memory access functions, these should work 7 * on any machine that has kernel and user data in the same 8 * address space, e.g. all NOMMU machines. 9 */ 10 #include <linux/string.h> 11 #include <asm-generic/access_ok.h> 12 13 #ifdef CONFIG_UACCESS_MEMCPY 14 #include <linux/unaligned.h> 15 16 static __always_inline int 17 __get_user_fn(size_t size, const void __user *from, void *to) 18 { 19 BUILD_BUG_ON(!__builtin_constant_p(size)); 20 21 switch (size) { 22 case 1: 23 *(u8 *)to = *((u8 __force *)from); 24 return 0; 25 case 2: 26 *(u16 *)to = get_unaligned((u16 __force *)from); 27 return 0; 28 case 4: 29 *(u32 *)to = get_unaligned((u32 __force *)from); 30 return 0; 31 case 8: 32 *(u64 *)to = get_unaligned((u64 __force *)from); 33 return 0; 34 default: 35 BUILD_BUG(); 36 return 0; 37 } 38 39 } 40 #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k) 41 42 static __always_inline int 43 __put_user_fn(size_t size, void __user *to, void *from) 44 { 45 BUILD_BUG_ON(!__builtin_constant_p(size)); 46 47 switch (size) { 48 case 1: 49 *(u8 __force *)to = *(u8 *)from; 50 return 0; 51 case 2: 52 put_unaligned(*(u16 *)from, (u16 __force *)to); 53 return 0; 54 case 4: 55 put_unaligned(*(u32 *)from, (u32 __force *)to); 56 return 0; 57 case 8: 58 put_unaligned(*(u64 *)from, (u64 __force *)to); 59 return 0; 60 default: 61 BUILD_BUG(); 62 return 0; 63 } 64 } 65 #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k) 66 67 #define __get_kernel_nofault(dst, src, type, err_label) \ 68 do { \ 69 *((type *)dst) = get_unaligned((type *)(src)); \ 70 if (0) /* make sure the label looks used to the compiler */ \ 71 goto err_label; \ 72 } while (0) 73 74 #define __put_kernel_nofault(dst, src, type, err_label) \ 75 do { \ 76 put_unaligned(*((type *)src), (type *)(dst)); \ 77 if (0) /* make sure the label looks used to the compiler */ \ 78 goto err_label; \ 79 } while (0) 80 81 static inline __must_check unsigned long 82 raw_copy_from_user(void *to, const void __user * from, unsigned long n) 83 { 84 memcpy(to, (const void __force *)from, n); 85 return 0; 86 } 87 88 static inline __must_check unsigned long 89 raw_copy_to_user(void __user *to, const void *from, unsigned long n) 90 { 91 memcpy((void __force *)to, from, n); 92 return 0; 93 } 94 #define INLINE_COPY_USER 95 #endif /* CONFIG_UACCESS_MEMCPY */ 96 97 /* 98 * These are the main single-value transfer routines. They automatically 99 * use the right size if we just have the right pointer type. 100 * This version just falls back to copy_{from,to}_user, which should 101 * provide a fast-path for small values. 102 */ 103 #define __put_user(x, ptr) \ 104 ({ \ 105 __typeof__(*(ptr)) __x = (x); \ 106 int __pu_err = -EFAULT; \ 107 __chk_user_ptr(ptr); \ 108 switch (sizeof (*(ptr))) { \ 109 case 1: \ 110 case 2: \ 111 case 4: \ 112 case 8: \ 113 __pu_err = __put_user_fn(sizeof (*(ptr)), \ 114 ptr, &__x); \ 115 break; \ 116 default: \ 117 __put_user_bad(); \ 118 break; \ 119 } \ 120 __pu_err; \ 121 }) 122 123 #define put_user(x, ptr) \ 124 ({ \ 125 void __user *__p = (ptr); \ 126 might_fault(); \ 127 access_ok(__p, sizeof(*ptr)) ? \ 128 __put_user((x), ((__typeof__(*(ptr)) __user *)__p)) : \ 129 -EFAULT; \ 130 }) 131 132 #ifndef __put_user_fn 133 134 static inline int __put_user_fn(size_t size, void __user *ptr, void *x) 135 { 136 return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0; 137 } 138 139 #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k) 140 141 #endif 142 143 extern int __put_user_bad(void) __attribute__((noreturn)); 144 145 #define __get_user(x, ptr) \ 146 ({ \ 147 int __gu_err = -EFAULT; \ 148 __chk_user_ptr(ptr); \ 149 switch (sizeof(*(ptr))) { \ 150 case 1: { \ 151 unsigned char __x = 0; \ 152 __gu_err = __get_user_fn(sizeof (*(ptr)), \ 153 ptr, &__x); \ 154 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 155 break; \ 156 }; \ 157 case 2: { \ 158 unsigned short __x = 0; \ 159 __gu_err = __get_user_fn(sizeof (*(ptr)), \ 160 ptr, &__x); \ 161 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 162 break; \ 163 }; \ 164 case 4: { \ 165 unsigned int __x = 0; \ 166 __gu_err = __get_user_fn(sizeof (*(ptr)), \ 167 ptr, &__x); \ 168 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 169 break; \ 170 }; \ 171 case 8: { \ 172 unsigned long long __x = 0; \ 173 __gu_err = __get_user_fn(sizeof (*(ptr)), \ 174 ptr, &__x); \ 175 (x) = *(__force __typeof__(*(ptr)) *) &__x; \ 176 break; \ 177 }; \ 178 default: \ 179 __get_user_bad(); \ 180 break; \ 181 } \ 182 __gu_err; \ 183 }) 184 185 #define get_user(x, ptr) \ 186 ({ \ 187 const void __user *__p = (ptr); \ 188 might_fault(); \ 189 access_ok(__p, sizeof(*ptr)) ? \ 190 __get_user((x), (__typeof__(*(ptr)) __user *)__p) :\ 191 ((x) = (__typeof__(*(ptr)))0,-EFAULT); \ 192 }) 193 194 #ifndef __get_user_fn 195 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) 196 { 197 return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0; 198 } 199 200 #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k) 201 202 #endif 203 204 extern int __get_user_bad(void) __attribute__((noreturn)); 205 206 /* 207 * Zero Userspace 208 */ 209 #ifndef __clear_user 210 static inline __must_check unsigned long 211 __clear_user(void __user *to, unsigned long n) 212 { 213 memset((void __force *)to, 0, n); 214 return 0; 215 } 216 #endif 217 218 static inline __must_check unsigned long 219 clear_user(void __user *to, unsigned long n) 220 { 221 might_fault(); 222 if (!access_ok(to, n)) 223 return n; 224 225 return __clear_user(to, n); 226 } 227 228 #include <asm/extable.h> 229 230 __must_check long strncpy_from_user(char *dst, const char __user *src, 231 long count); 232 __must_check long strnlen_user(const char __user *src, long n); 233 234 #endif /* __ASM_GENERIC_UACCESS_H */ 235