Files

78 lines
5.0 KiB
C

#ifndef _KERNEL_LIBKERN_UMEM_H
#define _KERNEL_LIBKERN_UMEM_H
#include <libkern/c_attrs.h>
#include <libkern/types.h>
#define USER_STR_MAXLEN (128)
#define USER_PTRARRAY_MAXLEN (128)
#define USER_STRARRAY_MAXLEN (128)
bool umem_validate_str(const char __user* us, size_t maxlen);
bool umem_validate_ptrarray(const void __user** uptrarr, size_t maxlen);
static ALWAYS_INLINE bool umem_validate_strarray(const char __user** s, size_t maxlen) { return umem_validate_ptrarray((const void __user**)s, maxlen); }
void* umem_bring_to_kernel(const void __user* data, size_t size);
char* umem_bring_to_kernel_str(const char __user* data, size_t maxlen);
char* umem_bring_to_kernel_str_with_len(const char __user* data, size_t size);
char** umem_bring_to_kernel_strarray(const char __user** udata, size_t maxlen);
void umem_copy_to_user(void __user* dest, const void* src, size_t length);
void umem_copy_from_user(void* dest, const void __user* src, size_t length);
static ALWAYS_INLINE void umem_get_user_1(uint8_t* ptr, uint8_t* uptr) { *ptr = *uptr; }
static ALWAYS_INLINE void umem_get_user_2(uint16_t* ptr, uint16_t* uptr) { *ptr = *uptr; }
static ALWAYS_INLINE void umem_get_user_4(uint32_t* ptr, uint32_t* uptr) { *ptr = *uptr; }
static ALWAYS_INLINE void umem_get_user_8(uint64_t* ptr, uint64_t* uptr) { *ptr = *uptr; }
static ALWAYS_INLINE void umem_put_user_1(uint8_t* val, uint8_t* uptr) { *uptr = *val; }
static ALWAYS_INLINE void umem_put_user_2(uint16_t* val, uint16_t* uptr) { *uptr = *val; }
static ALWAYS_INLINE void umem_put_user_4(uint32_t* val, uint32_t* uptr) { *uptr = *val; }
static ALWAYS_INLINE void umem_put_user_8(uint64_t* val, uint64_t* uptr) { *uptr = *val; }
#define __umem_put_user_impl_size(size, x, ptr) umem_put_user_##size(x, ptr)
#define umem_put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __user_val; \
__user_val = x; \
switch (sizeof(*(ptr))) { \
case 1: \
__umem_put_user_impl_size(1, (uint8_t*)&__user_val, (uint8_t*)ptr); \
break; \
case 2: \
__umem_put_user_impl_size(2, (uint16_t*)&__user_val, (uint16_t*)ptr); \
break; \
case 4: \
__umem_put_user_impl_size(4, (uint32_t*)&__user_val, (uint32_t*)ptr); \
break; \
case 8: \
__umem_put_user_impl_size(8, (uint64_t*)&__user_val, (uint64_t*)ptr); \
break; \
default: \
umem_copy_to_user(ptr, &__user_val, sizeof(*(ptr))); \
break; \
} \
})
#define __umem_get_user_impl_size(size, x, ptr) umem_get_user_##size(x, ptr)
#define umem_get_user(ptr, uptr) \
({ \
switch (sizeof(*(ptr))) { \
case 1: \
__umem_get_user_impl_size(1, (uint8_t*)ptr, (uint8_t*)uptr); \
break; \
case 2: \
__umem_get_user_impl_size(2, (uint16_t*)ptr, (uint16_t*)uptr); \
break; \
case 4: \
__umem_get_user_impl_size(4, (uint32_t*)ptr, (uint32_t*)uptr); \
break; \
case 8: \
__umem_get_user_impl_size(8, (uint64_t*)ptr, (uint64_t*)uptr); \
break; \
default: \
umem_copy_from_user(ptr, uptr, sizeof(*(ptr))); \
break; \
} \
})
#endif // _KERNEL_LIBKERN_UMEM_H