0001
0002 #ifndef __ASM_GENERIC_UACCESS_H
0003 #define __ASM_GENERIC_UACCESS_H
0004
0005
0006
0007
0008
0009
0010 #include <linux/string.h>
0011 #include <asm-generic/access_ok.h>
0012
0013 #ifdef CONFIG_UACCESS_MEMCPY
0014 #include <asm/unaligned.h>
0015
0016 static __always_inline int
0017 __get_user_fn(size_t size, const void __user *from, void *to)
0018 {
0019 BUILD_BUG_ON(!__builtin_constant_p(size));
0020
0021 switch (size) {
0022 case 1:
0023 *(u8 *)to = *((u8 __force *)from);
0024 return 0;
0025 case 2:
0026 *(u16 *)to = get_unaligned((u16 __force *)from);
0027 return 0;
0028 case 4:
0029 *(u32 *)to = get_unaligned((u32 __force *)from);
0030 return 0;
0031 case 8:
0032 *(u64 *)to = get_unaligned((u64 __force *)from);
0033 return 0;
0034 default:
0035 BUILD_BUG();
0036 return 0;
0037 }
0038
0039 }
0040 #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k)
0041
0042 static __always_inline int
0043 __put_user_fn(size_t size, void __user *to, void *from)
0044 {
0045 BUILD_BUG_ON(!__builtin_constant_p(size));
0046
0047 switch (size) {
0048 case 1:
0049 *(u8 __force *)to = *(u8 *)from;
0050 return 0;
0051 case 2:
0052 put_unaligned(*(u16 *)from, (u16 __force *)to);
0053 return 0;
0054 case 4:
0055 put_unaligned(*(u32 *)from, (u32 __force *)to);
0056 return 0;
0057 case 8:
0058 put_unaligned(*(u64 *)from, (u64 __force *)to);
0059 return 0;
0060 default:
0061 BUILD_BUG();
0062 return 0;
0063 }
0064 }
0065 #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k)
0066
0067 #define __get_kernel_nofault(dst, src, type, err_label) \
0068 do { \
0069 *((type *)dst) = get_unaligned((type *)(src)); \
0070 if (0) \
0071 goto err_label; \
0072 } while (0)
0073
0074 #define __put_kernel_nofault(dst, src, type, err_label) \
0075 do { \
0076 put_unaligned(*((type *)src), (type *)(dst)); \
0077 if (0) \
0078 goto err_label; \
0079 } while (0)
0080
0081 static inline __must_check unsigned long
0082 raw_copy_from_user(void *to, const void __user * from, unsigned long n)
0083 {
0084 memcpy(to, (const void __force *)from, n);
0085 return 0;
0086 }
0087
0088 static inline __must_check unsigned long
0089 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
0090 {
0091 memcpy((void __force *)to, from, n);
0092 return 0;
0093 }
0094 #define INLINE_COPY_FROM_USER
0095 #define INLINE_COPY_TO_USER
0096 #endif
0097
0098
0099
0100
0101
0102
0103
0104 #define __put_user(x, ptr) \
0105 ({ \
0106 __typeof__(*(ptr)) __x = (x); \
0107 int __pu_err = -EFAULT; \
0108 __chk_user_ptr(ptr); \
0109 switch (sizeof (*(ptr))) { \
0110 case 1: \
0111 case 2: \
0112 case 4: \
0113 case 8: \
0114 __pu_err = __put_user_fn(sizeof (*(ptr)), \
0115 ptr, &__x); \
0116 break; \
0117 default: \
0118 __put_user_bad(); \
0119 break; \
0120 } \
0121 __pu_err; \
0122 })
0123
0124 #define put_user(x, ptr) \
0125 ({ \
0126 void __user *__p = (ptr); \
0127 might_fault(); \
0128 access_ok(__p, sizeof(*ptr)) ? \
0129 __put_user((x), ((__typeof__(*(ptr)) __user *)__p)) : \
0130 -EFAULT; \
0131 })
0132
0133 #ifndef __put_user_fn
0134
0135 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
0136 {
0137 return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0;
0138 }
0139
0140 #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k)
0141
0142 #endif
0143
0144 extern int __put_user_bad(void) __attribute__((noreturn));
0145
0146 #define __get_user(x, ptr) \
0147 ({ \
0148 int __gu_err = -EFAULT; \
0149 __chk_user_ptr(ptr); \
0150 switch (sizeof(*(ptr))) { \
0151 case 1: { \
0152 unsigned char __x = 0; \
0153 __gu_err = __get_user_fn(sizeof (*(ptr)), \
0154 ptr, &__x); \
0155 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
0156 break; \
0157 }; \
0158 case 2: { \
0159 unsigned short __x = 0; \
0160 __gu_err = __get_user_fn(sizeof (*(ptr)), \
0161 ptr, &__x); \
0162 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
0163 break; \
0164 }; \
0165 case 4: { \
0166 unsigned int __x = 0; \
0167 __gu_err = __get_user_fn(sizeof (*(ptr)), \
0168 ptr, &__x); \
0169 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
0170 break; \
0171 }; \
0172 case 8: { \
0173 unsigned long long __x = 0; \
0174 __gu_err = __get_user_fn(sizeof (*(ptr)), \
0175 ptr, &__x); \
0176 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
0177 break; \
0178 }; \
0179 default: \
0180 __get_user_bad(); \
0181 break; \
0182 } \
0183 __gu_err; \
0184 })
0185
0186 #define get_user(x, ptr) \
0187 ({ \
0188 const void __user *__p = (ptr); \
0189 might_fault(); \
0190 access_ok(__p, sizeof(*ptr)) ? \
0191 __get_user((x), (__typeof__(*(ptr)) __user *)__p) :\
0192 ((x) = (__typeof__(*(ptr)))0,-EFAULT); \
0193 })
0194
0195 #ifndef __get_user_fn
0196 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
0197 {
0198 return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0;
0199 }
0200
0201 #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k)
0202
0203 #endif
0204
0205 extern int __get_user_bad(void) __attribute__((noreturn));
0206
0207
0208
0209
0210 #ifndef __clear_user
0211 static inline __must_check unsigned long
0212 __clear_user(void __user *to, unsigned long n)
0213 {
0214 memset((void __force *)to, 0, n);
0215 return 0;
0216 }
0217 #endif
0218
0219 static inline __must_check unsigned long
0220 clear_user(void __user *to, unsigned long n)
0221 {
0222 might_fault();
0223 if (!access_ok(to, n))
0224 return n;
0225
0226 return __clear_user(to, n);
0227 }
0228
0229 #include <asm/extable.h>
0230
0231 __must_check long strncpy_from_user(char *dst, const char __user *src,
0232 long count);
0233 __must_check long strnlen_user(const char __user *src, long n);
0234
0235 #endif