root/include/asm-generic/uaccess.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. raw_copy_from_user
  2. raw_copy_to_user
  3. set_fs
  4. __access_ok
  5. __put_user_fn
  6. __get_user_fn
  7. __strncpy_from_user
  8. strncpy_from_user
  9. strnlen_user
  10. __clear_user
  11. clear_user

   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 
  12 #ifdef CONFIG_UACCESS_MEMCPY
  13 static inline __must_check unsigned long
  14 raw_copy_from_user(void *to, const void __user * from, unsigned long n)
  15 {
  16         if (__builtin_constant_p(n)) {
  17                 switch(n) {
  18                 case 1:
  19                         *(u8 *)to = *(u8 __force *)from;
  20                         return 0;
  21                 case 2:
  22                         *(u16 *)to = *(u16 __force *)from;
  23                         return 0;
  24                 case 4:
  25                         *(u32 *)to = *(u32 __force *)from;
  26                         return 0;
  27 #ifdef CONFIG_64BIT
  28                 case 8:
  29                         *(u64 *)to = *(u64 __force *)from;
  30                         return 0;
  31 #endif
  32                 }
  33         }
  34 
  35         memcpy(to, (const void __force *)from, n);
  36         return 0;
  37 }
  38 
  39 static inline __must_check unsigned long
  40 raw_copy_to_user(void __user *to, const void *from, unsigned long n)
  41 {
  42         if (__builtin_constant_p(n)) {
  43                 switch(n) {
  44                 case 1:
  45                         *(u8 __force *)to = *(u8 *)from;
  46                         return 0;
  47                 case 2:
  48                         *(u16 __force *)to = *(u16 *)from;
  49                         return 0;
  50                 case 4:
  51                         *(u32 __force *)to = *(u32 *)from;
  52                         return 0;
  53 #ifdef CONFIG_64BIT
  54                 case 8:
  55                         *(u64 __force *)to = *(u64 *)from;
  56                         return 0;
  57 #endif
  58                 default:
  59                         break;
  60                 }
  61         }
  62 
  63         memcpy((void __force *)to, from, n);
  64         return 0;
  65 }
  66 #define INLINE_COPY_FROM_USER
  67 #define INLINE_COPY_TO_USER
  68 #endif /* CONFIG_UACCESS_MEMCPY */
  69 
  70 #define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
  71 
  72 #ifndef KERNEL_DS
  73 #define KERNEL_DS       MAKE_MM_SEG(~0UL)
  74 #endif
  75 
  76 #ifndef USER_DS
  77 #define USER_DS         MAKE_MM_SEG(TASK_SIZE - 1)
  78 #endif
  79 
  80 #ifndef get_fs
  81 #define get_fs()        (current_thread_info()->addr_limit)
  82 
  83 static inline void set_fs(mm_segment_t fs)
  84 {
  85         current_thread_info()->addr_limit = fs;
  86 }
  87 #endif
  88 
  89 #ifndef segment_eq
  90 #define segment_eq(a, b) ((a).seg == (b).seg)
  91 #endif
  92 
  93 #define access_ok(addr, size) __access_ok((unsigned long)(addr),(size))
  94 
  95 /*
  96  * The architecture should really override this if possible, at least
  97  * doing a check on the get_fs()
  98  */
  99 #ifndef __access_ok
 100 static inline int __access_ok(unsigned long addr, unsigned long size)
 101 {
 102         return 1;
 103 }
 104 #endif
 105 
 106 /*
 107  * These are the main single-value transfer routines.  They automatically
 108  * use the right size if we just have the right pointer type.
 109  * This version just falls back to copy_{from,to}_user, which should
 110  * provide a fast-path for small values.
 111  */
 112 #define __put_user(x, ptr) \
 113 ({                                                              \
 114         __typeof__(*(ptr)) __x = (x);                           \
 115         int __pu_err = -EFAULT;                                 \
 116         __chk_user_ptr(ptr);                                    \
 117         switch (sizeof (*(ptr))) {                              \
 118         case 1:                                                 \
 119         case 2:                                                 \
 120         case 4:                                                 \
 121         case 8:                                                 \
 122                 __pu_err = __put_user_fn(sizeof (*(ptr)),       \
 123                                          ptr, &__x);            \
 124                 break;                                          \
 125         default:                                                \
 126                 __put_user_bad();                               \
 127                 break;                                          \
 128          }                                                      \
 129         __pu_err;                                               \
 130 })
 131 
 132 #define put_user(x, ptr)                                        \
 133 ({                                                              \
 134         void __user *__p = (ptr);                               \
 135         might_fault();                                          \
 136         access_ok(__p, sizeof(*ptr)) ?          \
 137                 __put_user((x), ((__typeof__(*(ptr)) __user *)__p)) :   \
 138                 -EFAULT;                                        \
 139 })
 140 
 141 #ifndef __put_user_fn
 142 
 143 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
 144 {
 145         return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0;
 146 }
 147 
 148 #define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k)
 149 
 150 #endif
 151 
 152 extern int __put_user_bad(void) __attribute__((noreturn));
 153 
 154 #define __get_user(x, ptr)                                      \
 155 ({                                                              \
 156         int __gu_err = -EFAULT;                                 \
 157         __chk_user_ptr(ptr);                                    \
 158         switch (sizeof(*(ptr))) {                               \
 159         case 1: {                                               \
 160                 unsigned char __x = 0;                          \
 161                 __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 162                                          ptr, &__x);            \
 163                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 164                 break;                                          \
 165         };                                                      \
 166         case 2: {                                               \
 167                 unsigned short __x = 0;                         \
 168                 __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 169                                          ptr, &__x);            \
 170                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 171                 break;                                          \
 172         };                                                      \
 173         case 4: {                                               \
 174                 unsigned int __x = 0;                           \
 175                 __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 176                                          ptr, &__x);            \
 177                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 178                 break;                                          \
 179         };                                                      \
 180         case 8: {                                               \
 181                 unsigned long long __x = 0;                     \
 182                 __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 183                                          ptr, &__x);            \
 184                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 185                 break;                                          \
 186         };                                                      \
 187         default:                                                \
 188                 __get_user_bad();                               \
 189                 break;                                          \
 190         }                                                       \
 191         __gu_err;                                               \
 192 })
 193 
 194 #define get_user(x, ptr)                                        \
 195 ({                                                              \
 196         const void __user *__p = (ptr);                         \
 197         might_fault();                                          \
 198         access_ok(__p, sizeof(*ptr)) ?          \
 199                 __get_user((x), (__typeof__(*(ptr)) __user *)__p) :\
 200                 ((x) = (__typeof__(*(ptr)))0,-EFAULT);          \
 201 })
 202 
 203 #ifndef __get_user_fn
 204 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 205 {
 206         return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0;
 207 }
 208 
 209 #define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k)
 210 
 211 #endif
 212 
 213 extern int __get_user_bad(void) __attribute__((noreturn));
 214 
 215 /*
 216  * Copy a null terminated string from userspace.
 217  */
 218 #ifndef __strncpy_from_user
 219 static inline long
 220 __strncpy_from_user(char *dst, const char __user *src, long count)
 221 {
 222         char *tmp;
 223         strncpy(dst, (const char __force *)src, count);
 224         for (tmp = dst; *tmp && count > 0; tmp++, count--)
 225                 ;
 226         return (tmp - dst);
 227 }
 228 #endif
 229 
 230 static inline long
 231 strncpy_from_user(char *dst, const char __user *src, long count)
 232 {
 233         if (!access_ok(src, 1))
 234                 return -EFAULT;
 235         return __strncpy_from_user(dst, src, count);
 236 }
 237 
 238 /*
 239  * Return the size of a string (including the ending 0)
 240  *
 241  * Return 0 on exception, a value greater than N if too long
 242  */
 243 #ifndef __strnlen_user
 244 #define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
 245 #endif
 246 
 247 /*
 248  * Unlike strnlen, strnlen_user includes the nul terminator in
 249  * its returned count. Callers should check for a returned value
 250  * greater than N as an indication the string is too long.
 251  */
 252 static inline long strnlen_user(const char __user *src, long n)
 253 {
 254         if (!access_ok(src, 1))
 255                 return 0;
 256         return __strnlen_user(src, n);
 257 }
 258 
 259 /*
 260  * Zero Userspace
 261  */
 262 #ifndef __clear_user
 263 static inline __must_check unsigned long
 264 __clear_user(void __user *to, unsigned long n)
 265 {
 266         memset((void __force *)to, 0, n);
 267         return 0;
 268 }
 269 #endif
 270 
 271 static inline __must_check unsigned long
 272 clear_user(void __user *to, unsigned long n)
 273 {
 274         might_fault();
 275         if (!access_ok(to, n))
 276                 return n;
 277 
 278         return __clear_user(to, n);
 279 }
 280 
 281 #include <asm/extable.h>
 282 
 283 #endif /* __ASM_GENERIC_UACCESS_H */

/* [<][>][^][v][top][bottom][index][help] */