linux/include/asm-generic/uaccess.h
<<
>>
Prefs
   1#ifndef __ASM_GENERIC_UACCESS_H
   2#define __ASM_GENERIC_UACCESS_H
   3
   4/*
   5 * User space memory access functions, these should work
   6 * on any machine that has kernel and user data in the same
   7 * address space, e.g. all NOMMU machines.
   8 */
   9#include <linux/string.h>
  10
  11#include <asm/segment.h>
  12
  13#define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
  14
  15#ifndef KERNEL_DS
  16#define KERNEL_DS       MAKE_MM_SEG(~0UL)
  17#endif
  18
  19#ifndef USER_DS
  20#define USER_DS         MAKE_MM_SEG(TASK_SIZE - 1)
  21#endif
  22
  23#ifndef get_fs
  24#define get_ds()        (KERNEL_DS)
  25#define get_fs()        (current_thread_info()->addr_limit)
  26
  27static inline void set_fs(mm_segment_t fs)
  28{
  29        current_thread_info()->addr_limit = fs;
  30}
  31#endif
  32
  33#ifndef segment_eq
  34#define segment_eq(a, b) ((a).seg == (b).seg)
  35#endif
  36
  37#define access_ok(type, addr, size) __access_ok((unsigned long)(addr),(size))
  38
  39/*
  40 * The architecture should really override this if possible, at least
  41 * doing a check on the get_fs()
  42 */
  43#ifndef __access_ok
  44static inline int __access_ok(unsigned long addr, unsigned long size)
  45{
  46        return 1;
  47}
  48#endif
  49
  50/*
  51 * These are the main single-value transfer routines.  They automatically
  52 * use the right size if we just have the right pointer type.
  53 * This version just falls back to copy_{from,to}_user, which should
  54 * provide a fast-path for small values.
  55 */
  56#define __put_user(x, ptr) \
  57({                                                              \
  58        __typeof__(*(ptr)) __x = (x);                           \
  59        int __pu_err = -EFAULT;                                 \
  60        __chk_user_ptr(ptr);                                    \
  61        switch (sizeof (*(ptr))) {                              \
  62        case 1:                                                 \
  63        case 2:                                                 \
  64        case 4:                                                 \
  65        case 8:                                                 \
  66                __pu_err = __put_user_fn(sizeof (*(ptr)),       \
  67                                         ptr, &__x);            \
  68                break;                                          \
  69        default:                                                \
  70                __put_user_bad();                               \
  71                break;                                          \
  72         }                                                      \
  73        __pu_err;                                               \
  74})
  75
  76#define put_user(x, ptr)                                        \
  77({                                                              \
  78        void *__p = (ptr);                                      \
  79        might_fault();                                          \
  80        access_ok(VERIFY_WRITE, __p, sizeof(*ptr)) ?            \
  81                __put_user((x), ((__typeof__(*(ptr)) *)__p)) :  \
  82                -EFAULT;                                        \
  83})
  84
  85#ifndef __put_user_fn
  86
  87static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
  88{
  89        return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0;
  90}
  91
  92#define __put_user_fn(sz, u, k) __put_user_fn(sz, u, k)
  93
  94#endif
  95
  96extern int __put_user_bad(void) __attribute__((noreturn));
  97
  98#define __get_user(x, ptr)                                      \
  99({                                                              \
 100        int __gu_err = -EFAULT;                                 \
 101        __chk_user_ptr(ptr);                                    \
 102        switch (sizeof(*(ptr))) {                               \
 103        case 1: {                                               \
 104                unsigned char __x = 0;                          \
 105                __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 106                                         ptr, &__x);            \
 107                (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 108                break;                                          \
 109        };                                                      \
 110        case 2: {                                               \
 111                unsigned short __x = 0;                         \
 112                __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 113                                         ptr, &__x);            \
 114                (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 115                break;                                          \
 116        };                                                      \
 117        case 4: {                                               \
 118                unsigned int __x = 0;                           \
 119                __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 120                                         ptr, &__x);            \
 121                (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 122                break;                                          \
 123        };                                                      \
 124        case 8: {                                               \
 125                unsigned long long __x = 0;                     \
 126                __gu_err = __get_user_fn(sizeof (*(ptr)),       \
 127                                         ptr, &__x);            \
 128                (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
 129                break;                                          \
 130        };                                                      \
 131        default:                                                \
 132                __get_user_bad();                               \
 133                break;                                          \
 134        }                                                       \
 135        __gu_err;                                               \
 136})
 137
 138#define get_user(x, ptr)                                        \
 139({                                                              \
 140        const void *__p = (ptr);                                \
 141        might_fault();                                          \
 142        access_ok(VERIFY_READ, __p, sizeof(*ptr)) ?             \
 143                __get_user((x), (__typeof__(*(ptr)) *)__p) :    \
 144                ((x) = (__typeof__(*(ptr)))0,-EFAULT);          \
 145})
 146
 147#ifndef __get_user_fn
 148static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
 149{
 150        return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0;
 151}
 152
 153#define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k)
 154
 155#endif
 156
 157extern int __get_user_bad(void) __attribute__((noreturn));
 158
 159/*
 160 * Copy a null terminated string from userspace.
 161 */
 162#ifndef __strncpy_from_user
 163static inline long
 164__strncpy_from_user(char *dst, const char __user *src, long count)
 165{
 166        char *tmp;
 167        strncpy(dst, (const char __force *)src, count);
 168        for (tmp = dst; *tmp && count > 0; tmp++, count--)
 169                ;
 170        return (tmp - dst);
 171}
 172#endif
 173
 174static inline long
 175strncpy_from_user(char *dst, const char __user *src, long count)
 176{
 177        if (!access_ok(VERIFY_READ, src, 1))
 178                return -EFAULT;
 179        return __strncpy_from_user(dst, src, count);
 180}
 181
 182/*
 183 * Return the size of a string (including the ending 0)
 184 *
 185 * Return 0 on exception, a value greater than N if too long
 186 */
 187#ifndef __strnlen_user
 188#define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
 189#endif
 190
 191/*
 192 * Unlike strnlen, strnlen_user includes the nul terminator in
 193 * its returned count. Callers should check for a returned value
 194 * greater than N as an indication the string is too long.
 195 */
 196static inline long strnlen_user(const char __user *src, long n)
 197{
 198        if (!access_ok(VERIFY_READ, src, 1))
 199                return 0;
 200        return __strnlen_user(src, n);
 201}
 202
 203/*
 204 * Zero Userspace
 205 */
 206#ifndef __clear_user
 207static inline __must_check unsigned long
 208__clear_user(void __user *to, unsigned long n)
 209{
 210        memset((void __force *)to, 0, n);
 211        return 0;
 212}
 213#endif
 214
 215static inline __must_check unsigned long
 216clear_user(void __user *to, unsigned long n)
 217{
 218        might_fault();
 219        if (!access_ok(VERIFY_WRITE, to, n))
 220                return n;
 221
 222        return __clear_user(to, n);
 223}
 224
 225#include <asm/extable.h>
 226
 227#endif /* __ASM_GENERIC_UACCESS_H */
 228