1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2020, Linaro Limited 5 */ 6 #ifndef __KERNEL_USER_ACCESS_H 7 #define __KERNEL_USER_ACCESS_H 8 9 #include <assert.h> 10 #include <kernel/user_access_arch.h> 11 #include <tee_api_types.h> 12 #include <types_ext.h> 13 14 #ifdef CFG_WITH_USER_TA 15 TEE_Result check_user_access(uint32_t flags, const void *uaddr, size_t len); 16 TEE_Result copy_from_user_private(void *kaddr, const void *uaddr, size_t len); 17 TEE_Result copy_from_user(void *kaddr, const void *uaddr, size_t len); 18 #else 19 static inline TEE_Result check_user_access(uint32_t flags __unused, 20 const void *uaddr __unused, 21 size_t len __unused) 22 { 23 return TEE_ERROR_NOT_SUPPORTED; 24 } 25 26 static inline TEE_Result copy_from_user_private(void *kaddr __unused, 27 const void *uaddr __unused, 28 size_t len __unused) 29 { 30 return TEE_ERROR_NOT_SUPPORTED; 31 } 32 33 static inline TEE_Result copy_from_user(void *kaddr __unused, 34 const void *uaddr __unused, 35 size_t len __unused) 36 { 37 return TEE_ERROR_NOT_SUPPORTED; 38 } 39 40 #endif 41 42 /* 43 * bb_alloc() - Allocate a bounce buffer 44 * @len: Length of bounce buffer 45 * 46 * The bounce buffer is allocated from a per user TA context region reserved 47 * for bounce buffers. Buffers are allocated in a stack like fashion so 48 * only the last buffer can be free. Buffers generally don't have to be 49 * freed, all bounce buffer allocations are reset on each syscall entry. 50 * 51 * Return NULL on failure or a valid pointer on success. 52 */ 53 void *bb_alloc(size_t len); 54 55 /* 56 * bb_free() - Free a bounce buffer 57 * @bb: Buffer 58 * @len: Length of buffer 59 * 60 * The bounce buffer is only freed if it is last on the stack of allocated 61 * bounce buffers. This function does normally not need to be called, see 62 * description of bb_alloc(). 63 */ 64 void bb_free(void *bb, size_t len); 65 66 /* 67 * bb_reset() - Reset bounce buffer allocation 68 * 69 * Resets the bounce buffer allocatation state, old pointers allocated 70 * with bb_alloc() should not be used any longer. 71 */ 72 void bb_reset(void); 73 74 TEE_Result copy_to_user_private(void *uaddr, const void *kaddr, size_t len); 75 TEE_Result copy_to_user(void *uaddr, const void *kaddr, size_t len); 76 77 TEE_Result clear_user(void *uaddr, size_t n); 78 79 size_t strnlen_user(const void *s, size_t n); 80 81 /* 82 * bb_memdup_user() - Duplicate a user-space buffer into a bounce buffer 83 * @src: Pointer to the user buffer to be duplicated. 84 * @len: Length of the user buffer to be duplicated. 85 * @p: Holds duplicated bounce buffer on success, or unchanged on failure. 86 * Note that the returned buffer is allocated by bb_alloc() and 87 * normally doesn't have to be freed. 88 * Return TEE_SUCCESS on success. 89 * Return TEE_ERROR_OUT_OF_MEMORY or TEE_ERROR_ACCESS_DENIED on error. 90 */ 91 TEE_Result bb_memdup_user(const void *src, size_t len, void **p); 92 93 /* 94 * bb_memdup_user_private() - Duplicate a private user-space buffer 95 * @src: Pointer to the user buffer to be duplicated. The buffer should 96 * be private to current TA (i.e., !TEE_MEMORY_ACCESS_ANY_OWNER). 97 * @len: Length of the user buffer to be duplicated. 98 * @p: Holds duplicated kernel buffer on success, or unchanged on failure. 99 * Note that the returned buffer is allocated by bb_alloc() and 100 * normally doesn't have to be freed. 101 * Return TEE_SUCCESS on success. 102 * Return TEE_ERROR_OUT_OF_MEMORY or TEE_ERROR_ACCESS_DENIED on error. 103 */ 104 TEE_Result bb_memdup_user_private(const void *src, size_t len, void **p); 105 106 /* 107 * bb_strndup_user() - Duplicate a user-space string into a bounce buffer 108 * @src: Pointer to the user string to be duplicated. 109 * @maxlen: Maximum length of the user string 110 * @dst: Holds duplicated string on success, or unchanged on failure. 111 * @dstlen: Length of string, excluding the terminating zero, returned in 112 * @dst. 113 * 114 * Note that the returned buffer is allocated by bb_alloc() and normally 115 * doesn't have to be freed. But if it is to be freed the supplied length 116 * to bb_free() should be dstlen + 1. 117 * 118 * Return TEE_SUCCESS on success. 119 * Return TEE_ERROR_OUT_OF_MEMORY or TEE_ERROR_ACCESS_DENIED on error. 120 */ 121 TEE_Result bb_strndup_user(const char *src, size_t maxlen, char **dst, 122 size_t *dstlen); 123 124 TEE_Result copy_kaddr_to_uref(uint32_t *uref, void *kaddr); 125 126 uint32_t kaddr_to_uref(void *kaddr); 127 vaddr_t uref_to_vaddr(uint32_t uref); 128 static inline void *uref_to_kaddr(uint32_t uref) 129 { 130 return (void *)uref_to_vaddr(uref); 131 } 132 133 #define GET_USER_SCALAR(_x, _p) ({ \ 134 TEE_Result __res = TEE_SUCCESS; \ 135 typeof(_p) __p = (_p); \ 136 \ 137 static_assert(sizeof(_x) == sizeof(*__p)); \ 138 \ 139 __res = copy_from_user(&(_x), (const void *)__p, sizeof(*__p)); \ 140 __res; \ 141 }) 142 143 #define PUT_USER_SCALAR(_x, _p) ({ \ 144 TEE_Result __res = TEE_SUCCESS; \ 145 typeof(_p) __p = (_p); \ 146 \ 147 static_assert(sizeof(_x) == sizeof(*__p)); \ 148 \ 149 __res = copy_to_user((void *)__p, &(_x), sizeof(*__p)); \ 150 __res; \ 151 }) 152 153 #endif /*__KERNEL_USER_ACCESS_H*/ 154