xref: /optee_os/core/include/kernel/user_access.h (revision e59bc1dbfdd496810cf8afef4a998ee06af1cc92)
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