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