linux/arch/score/include/asm/uaccess.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __SCORE_UACCESS_H
   3#define __SCORE_UACCESS_H
   4
   5#include <linux/kernel.h>
   6#include <asm/extable.h>
   7
   8#define get_ds()                (KERNEL_DS)
   9#define get_fs()                (current_thread_info()->addr_limit)
  10#define segment_eq(a, b)        ((a).seg == (b).seg)
  11
  12/*
  13 * Is a address valid? This does a straighforward calculation rather
  14 * than tests.
  15 *
  16 * Address valid if:
  17 *  - "addr" doesn't have any high-bits set
  18 *  - AND "size" doesn't have any high-bits set
  19 *  - AND "addr+size" doesn't have any high-bits set
  20 *  - OR we are in kernel mode.
  21 *
  22 * __ua_size() is a trick to avoid runtime checking of positive constant
  23 * sizes; for those we already know at compile time that the size is ok.
  24 */
  25#define __ua_size(size)                                                 \
  26        ((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
  27
  28/*
  29 * access_ok: - Checks if a user space pointer is valid
  30 * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
  31 *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
  32 *        to write to a block, it is always safe to read from it.
  33 * @addr: User space pointer to start of block to check
  34 * @size: Size of block to check
  35 *
  36 * Context: User context only. This function may sleep if pagefaults are
  37 *          enabled.
  38 *
  39 * Checks if a pointer to a block of memory in user space is valid.
  40 *
  41 * Returns true (nonzero) if the memory block may be valid, false (zero)
  42 * if it is definitely invalid.
  43 *
  44 * Note that, depending on architecture, this function probably just
  45 * checks that the pointer is in the user space range - after calling
  46 * this function, memory access functions may still return -EFAULT.
  47 */
  48
  49#define __access_ok(addr, size)                                 \
  50        (((long)((get_fs().seg) &                               \
  51                 ((addr) | ((addr) + (size)) |                  \
  52                  __ua_size(size)))) == 0)
  53
  54#define access_ok(type, addr, size)                             \
  55        likely(__access_ok((unsigned long)(addr), (size)))
  56
  57/*
  58 * put_user: - Write a simple value into user space.
  59 * @x:   Value to copy to user space.
  60 * @ptr: Destination address, in user space.
  61 *
  62 * Context: User context only. This function may sleep if pagefaults are
  63 *          enabled.
  64 *
  65 * This macro copies a single simple value from kernel space to user
  66 * space.  It supports simple types like char and int, but not larger
  67 * data types like structures or arrays.
  68 *
  69 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  70 * to the result of dereferencing @ptr.
  71 *
  72 * Returns zero on success, or -EFAULT on error.
  73 */
  74#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
  75
  76/*
  77 * get_user: - Get a simple variable from user space.
  78 * @x:   Variable to store result.
  79 * @ptr: Source address, in user space.
  80 *
  81 * Context: User context only. This function may sleep if pagefaults are
  82 *          enabled.
  83 *
  84 * This macro copies a single simple variable from user space to kernel
  85 * space.  It supports simple types like char and int, but not larger
  86 * data types like structures or arrays.
  87 *
  88 * @ptr must have pointer-to-simple-variable type, and the result of
  89 * dereferencing @ptr must be assignable to @x without a cast.
  90 *
  91 * Returns zero on success, or -EFAULT on error.
  92 * On error, the variable @x is set to zero.
  93 */
  94#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
  95
  96/*
  97 * __put_user: - Write a simple value into user space, with less checking.
  98 * @x:   Value to copy to user space.
  99 * @ptr: Destination address, in user space.
 100 *
 101 * Context: User context only. This function may sleep if pagefaults are
 102 *          enabled.
 103 *
 104 * This macro copies a single simple value from kernel space to user
 105 * space.  It supports simple types like char and int, but not larger
 106 * data types like structures or arrays.
 107 *
 108 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
 109 * to the result of dereferencing @ptr.
 110 *
 111 * Caller must check the pointer with access_ok() before calling this
 112 * function.
 113 *
 114 * Returns zero on success, or -EFAULT on error.
 115 */
 116#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
 117
 118/*
 119 * __get_user: - Get a simple variable from user space, with less checking.
 120 * @x:   Variable to store result.
 121 * @ptr: Source address, in user space.
 122 *
 123 * Context: User context only. This function may sleep if pagefaults are
 124 *          enabled.
 125 *
 126 * This macro copies a single simple variable from user space to kernel
 127 * space.  It supports simple types like char and int, but not larger
 128 * data types like structures or arrays.
 129 *
 130 * @ptr must have pointer-to-simple-variable type, and the result of
 131 * dereferencing @ptr must be assignable to @x without a cast.
 132 *
 133 * Caller must check the pointer with access_ok() before calling this
 134 * function.
 135 *
 136 * Returns zero on success, or -EFAULT on error.
 137 * On error, the variable @x is set to zero.
 138 */
 139#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
 140
 141struct __large_struct { unsigned long buf[100]; };
 142#define __m(x) (*(struct __large_struct __user *)(x))
 143
 144/*
 145 * Yuck.  We need two variants, one for 64bit operation and one
 146 * for 32 bit mode and old iron.
 147 */
 148extern void __get_user_unknown(void);
 149
 150#define __get_user_common(val, size, ptr)                               \
 151do {                                                                    \
 152        switch (size) {                                                 \
 153        case 1:                                                         \
 154                __get_user_asm(val, "lb", ptr);                         \
 155                break;                                                  \
 156        case 2:                                                         \
 157                __get_user_asm(val, "lh", ptr);                         \
 158                 break;                                                 \
 159        case 4:                                                         \
 160                __get_user_asm(val, "lw", ptr);                         \
 161                 break;                                                 \
 162        case 8:                                                         \
 163                if (__copy_from_user((void *)&val, ptr, 8) == 0)        \
 164                        __gu_err = 0;                                   \
 165                else                                                    \
 166                        __gu_err = -EFAULT;                             \
 167                break;                                                  \
 168        default:                                                        \
 169                __get_user_unknown();                                   \
 170                break;                                                  \
 171        }                                                               \
 172} while (0)
 173
 174#define __get_user_nocheck(x, ptr, size)                                \
 175({                                                                      \
 176        long __gu_err = 0;                                              \
 177        __get_user_common((x), size, ptr);                              \
 178        __gu_err;                                                       \
 179})
 180
 181#define __get_user_check(x, ptr, size)                                  \
 182({                                                                      \
 183        long __gu_err = -EFAULT;                                        \
 184        const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);              \
 185                                                                        \
 186        if (likely(access_ok(VERIFY_READ, __gu_ptr, size)))             \
 187                __get_user_common((x), size, __gu_ptr);                 \
 188        else                                                            \
 189                (x) = 0;                                                \
 190                                                                        \
 191        __gu_err;                                                       \
 192})
 193
 194#define __get_user_asm(val, insn, addr)                                 \
 195{                                                                       \
 196        long __gu_tmp;                                                  \
 197                                                                        \
 198        __asm__ __volatile__(                                           \
 199                "1:" insn " %1, %3\n"                                   \
 200                "2:\n"                                                  \
 201                ".section .fixup,\"ax\"\n"                              \
 202                "3:li   %0, %4\n"                                       \
 203                "li     %1, 0\n"                                        \
 204                "j      2b\n"                                           \
 205                ".previous\n"                                           \
 206                ".section __ex_table,\"a\"\n"                           \
 207                ".word  1b, 3b\n"                                       \
 208                ".previous\n"                                           \
 209                : "=r" (__gu_err), "=r" (__gu_tmp)                      \
 210                : "0" (0), "o" (__m(addr)), "i" (-EFAULT));             \
 211                                                                        \
 212                (val) = (__typeof__(*(addr))) __gu_tmp;                 \
 213}
 214
 215/*
 216 * Yuck.  We need two variants, one for 64bit operation and one
 217 * for 32 bit mode and old iron.
 218 */
 219#define __put_user_nocheck(val, ptr, size)                              \
 220({                                                                      \
 221        __typeof__(*(ptr)) __pu_val;                                    \
 222        long __pu_err = 0;                                              \
 223                                                                        \
 224        __pu_val = (val);                                               \
 225        switch (size) {                                                 \
 226        case 1:                                                         \
 227                __put_user_asm("sb", ptr);                              \
 228                break;                                                  \
 229        case 2:                                                         \
 230                __put_user_asm("sh", ptr);                              \
 231                break;                                                  \
 232        case 4:                                                         \
 233                __put_user_asm("sw", ptr);                              \
 234                break;                                                  \
 235        case 8:                                                         \
 236                if ((__copy_to_user((void *)ptr, &__pu_val, 8)) == 0)   \
 237                        __pu_err = 0;                                   \
 238                else                                                    \
 239                        __pu_err = -EFAULT;                             \
 240                break;                                                  \
 241        default:                                                        \
 242                 __put_user_unknown();                                  \
 243                 break;                                                 \
 244        }                                                               \
 245        __pu_err;                                                       \
 246})
 247
 248
 249#define __put_user_check(val, ptr, size)                                \
 250({                                                                      \
 251        __typeof__(*(ptr)) __user *__pu_addr = (ptr);                   \
 252        __typeof__(*(ptr)) __pu_val = (val);                            \
 253        long __pu_err = -EFAULT;                                        \
 254                                                                        \
 255        if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) {         \
 256                switch (size) {                                         \
 257                case 1:                                                 \
 258                        __put_user_asm("sb", __pu_addr);                \
 259                        break;                                          \
 260                case 2:                                                 \
 261                        __put_user_asm("sh", __pu_addr);                \
 262                        break;                                          \
 263                case 4:                                                 \
 264                        __put_user_asm("sw", __pu_addr);                \
 265                        break;                                          \
 266                case 8:                                                 \
 267                        if ((__copy_to_user((void *)__pu_addr, &__pu_val, 8)) == 0)\
 268                                __pu_err = 0;                           \
 269                        else                                            \
 270                                __pu_err = -EFAULT;                     \
 271                        break;                                          \
 272                default:                                                \
 273                        __put_user_unknown();                           \
 274                        break;                                          \
 275                }                                                       \
 276        }                                                               \
 277        __pu_err;                                                       \
 278})
 279
 280#define __put_user_asm(insn, ptr)                                       \
 281        __asm__ __volatile__(                                           \
 282                "1:" insn " %2, %3\n"                                   \
 283                "2:\n"                                                  \
 284                ".section .fixup,\"ax\"\n"                              \
 285                "3:li %0, %4\n"                                         \
 286                "j 2b\n"                                                \
 287                ".previous\n"                                           \
 288                ".section __ex_table,\"a\"\n"                           \
 289                ".word 1b, 3b\n"                                        \
 290                ".previous\n"                                           \
 291                : "=r" (__pu_err)                                       \
 292                : "0" (0), "r" (__pu_val), "o" (__m(ptr)),              \
 293                  "i" (-EFAULT));
 294
 295extern void __put_user_unknown(void);
 296extern int __copy_tofrom_user(void *to, const void *from, unsigned long len);
 297
 298static inline unsigned long
 299raw_copy_from_user(void *to, const void __user *from, unsigned long len)
 300{
 301        return __copy_tofrom_user(to, (__force const void *)from, len);
 302}
 303
 304static inline unsigned long
 305raw_copy_to_user(void __user *to, const void *from, unsigned long len)
 306{
 307        return __copy_tofrom_user((__force void *)to, from, len);
 308}
 309
 310#define INLINE_COPY_FROM_USER
 311#define INLINE_COPY_TO_USER
 312
 313/*
 314 * __clear_user: - Zero a block of memory in user space, with less checking.
 315 * @to:   Destination address, in user space.
 316 * @n:    Number of bytes to zero.
 317 *
 318 * Zero a block of memory in user space.  Caller must check
 319 * the specified block with access_ok() before calling this function.
 320 *
 321 * Returns number of bytes that could not be cleared.
 322 * On success, this will be zero.
 323 */
 324extern unsigned long __clear_user(void __user *src, unsigned long size);
 325
 326static inline unsigned long clear_user(char *src, unsigned long size)
 327{
 328        if (access_ok(VERIFY_WRITE, src, size))
 329                return __clear_user(src, size);
 330
 331        return -EFAULT;
 332}
 333/*
 334 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
 335 * @dst:   Destination address, in kernel space.  This buffer must be at
 336 *         least @count bytes long.
 337 * @src:   Source address, in user space.
 338 * @count: Maximum number of bytes to copy, including the trailing NUL.
 339 *
 340 * Copies a NUL-terminated string from userspace to kernel space.
 341 * Caller must check the specified block with access_ok() before calling
 342 * this function.
 343 *
 344 * On success, returns the length of the string (not including the trailing
 345 * NUL).
 346 *
 347 * If access to userspace fails, returns -EFAULT (some data may have been
 348 * copied).
 349 *
 350 * If @count is smaller than the length of the string, copies @count bytes
 351 * and returns @count.
 352 */
 353extern int __strncpy_from_user(char *dst, const char *src, long len);
 354
 355static inline int strncpy_from_user(char *dst, const char *src, long len)
 356{
 357        if (access_ok(VERIFY_READ, src, 1))
 358                return __strncpy_from_user(dst, src, len);
 359
 360        return -EFAULT;
 361}
 362
 363extern int __strnlen_user(const char *str, long len);
 364static inline long strnlen_user(const char __user *str, long len)
 365{
 366        if (!access_ok(VERIFY_READ, str, 0))
 367                return 0;
 368        else            
 369                return __strnlen_user(str, len);
 370}
 371
 372#endif /* __SCORE_UACCESS_H */
 373
 374