44extern void *
DupUserMem(
const void *ptr,
size_t len,
int needCopy);
45extern int GetFullpath(
int fd,
const char *path,
char **fullpath);
46extern int UserPathCopy(
const char *userPath,
char **pathBuf);
48#define CHECK_ASPACE(ptr, len, ...) \
50 if (ptr != NULL && len != 0) { \
51 if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)ptr, len)) { \
54 return -get_errno(); \
56 LosVmSpace *__aspace = OsCurrProcessGet()->vmSpace; \
57 (VOID)LOS_MuxAcquire(&__aspace->regionMux); \
58 if (CheckRegion(__aspace, (VADDR_T)(UINTPTR)ptr, len) == -1) { \
59 (VOID)LOS_MuxRelease(&__aspace->regionMux); \
62 return -get_errno(); \
64 (VOID)LOS_MuxRelease(&__aspace->regionMux); \
68#define LEN(ptr) ((ptr) ? *(ptr) : 0)
70#define DUP_FROM_USER_(ptr, size, copy, ...) \
71 __typeof(ptr) ptr##bak = ptr; \
72 if (ptr != NULL && (size) != 0) { \
73 ptr = DupUserMem(ptr, size, copy); \
77 return -get_errno(); \
85#define DUP_FROM_USER(ptr, size, ...) \
86 DUP_FROM_USER_(ptr, size, 1, ##__VA_ARGS__)
88#define DUP_FROM_USER_NOCOPY(ptr, size, ...) \
89 DUP_FROM_USER_(ptr, size, 0, ##__VA_ARGS__)
91#define DUP_TO_USER(ptr, size, ...) \
93 if (ptr != NULL && (size) != 0) { \
94 if (LOS_ArchCopyToUser(ptr##bak, ptr, size) != 0) { \
97 return -get_errno(); \
102#define FREE_DUP(ptr) \
104 if (ptr != ptr##bak) { \
105 LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \
110#define CPY_FROM_USER(ptr) \
111 __typeof(*ptr) ptr##cpy = {0}, *ptr##bak = ptr; \
113 if (LOS_ArchCopyFromUser((void*)&ptr##cpy, ptr##bak, sizeof(*ptr##bak)) != 0) { \
115 return -get_errno(); \
120#define CPY_TO_USER(ptr, ...) \
122 if (LOS_ArchCopyToUser(ptr##bak, ptr, sizeof(*ptr)) != 0) { \
125 return -get_errno(); \
131#define CONST_CAST(ptr) ((__typeof(ptr##_NONCONST))ptr)
133#define CHECK_FIELD_ASPACE(ptr, field, len) \
136 CHECK_ASPACE(ptr->field, len); \
140#define CHECK_ARRAY_FIELD_ASPACE(ptr, arr, arrlen, field, len, ...) \
142 if (ptr != NULL && ptr->arr != NULL) { \
143 for (size_t i = 0; i < arrlen; i++) { \
144 CHECK_ASPACE(ptr->arr[i].field, ptr->arr[i].len, ##__VA_ARGS__); \
149#define DUP_FIELD_FROM_USER_(ptr, field, size, copy, ...) \
151 if (ptr != NULL && ptr->field != NULL && (size) != 0) { \
152 CONST_CAST(ptr)->field = DupUserMem(ptr->field, size, copy); \
153 if (ptr->field == NULL) { \
155 return -get_errno(); \
160#define DUP_FIELD_FROM_USER(ptr, field, size, ...) \
161 DUP_FIELD_FROM_USER_(ptr, field, size, 1, ##__VA_ARGS__)
163#define DUP_FIELD_FROM_USER_NOCOPY(ptr, field, size, ...) \
164 DUP_FIELD_FROM_USER_(ptr, field, size, 0, ##__VA_ARGS__)
167#define DUP_ARRAY_FIELD_FROM_USER_(ext, ptr, arr, arrlen, field, len, ...) \
168 __typeof(*ptr##_NONCONST) ptr##arr##cpy = ptr##cpybak, ptr##arr##cpybak = ptr##cpybak; \
169 __typeof(ptr##_NONCONST) ptr##arr = ptr ? &ptr##arr##cpy : NULL, ptr##arr##_NONCONST = NULL; \
170 DUP_FIELD_FROM_USER(ptr##arr, arr, arrlen * sizeof(ptr->arr[0]), ##__VA_ARGS__); \
171 if (ptr != NULL && ptr->arr != NULL) { \
173 for (; i < arrlen; i++) { \
174 DUP_FIELD_FROM_USER##ext(ptr, arr[i].field, ptr->arr[i].len, break); \
177 FREE_DUP_ARRAY_FIELD(ptr, arr, i, field); \
179 return -get_errno(); \
183#define DUP_ARRAY_FIELD_FROM_USER(ptr, arr, arrlen, field, len, ...) \
184 DUP_ARRAY_FIELD_FROM_USER_(, ptr, arr, arrlen, field, len, ##__VA_ARGS__)
186#define DUP_ARRAY_FIELD_FROM_USER_NOCOPY(ptr, arr, arrlen, field, len, ...) \
187 DUP_ARRAY_FIELD_FROM_USER_(_NOCOPY, ptr, arr, arrlen, field, len, ##__VA_ARGS__)
189#define FREE_DUP_FIELD(ptr, field) \
191 if (ptr != NULL && ptr->field != ptr##cpybak.field) { \
192 LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr->field); \
193 CONST_CAST(ptr)->field = ptr##cpybak.field; \
198#define FREE_DUP_ARRAY_FIELD(ptr, arr, arrlen, field) \
199 if (ptr != NULL && ptr->arr != NULL && arrlen != 0) { \
200 __typeof(ptr##cpybak.arr) tmp = ptr##cpybak.arr; \
201 ptr##cpybak.arr = ptr##arr->arr; \
202 for (size_t j = 0; j < arrlen; j++) { \
203 FREE_DUP_FIELD(ptr, arr[j].field); \
205 ptr##cpybak.arr = tmp; \
207 FREE_DUP_FIELD(ptr##arr, arr);
209#define CPY_FROM_CONST_USER(NonConstType, ptr) \
210 CPY_FROM_USER(ptr); \
211 NonConstType *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy; \
214#define CPY_FROM_NONCONST_USER(ptr) \
215 CPY_FROM_USER(ptr); \
216 __typeof(*ptr) *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy;
218#define DUP_FIELD_TO_USER(ptr, field, size, ...) \
220 if (ptr != NULL && ptr->field != NULL && (size) != 0) { \
221 if (LOS_ArchCopyToUser(ptr##cpybak.field, ptr->field, size) != 0 || \
222 LOS_ArchCopyToUser(&ptr##bak->field, &ptr##cpybak.field, sizeof(__typeof(ptr##cpybak.field))) != 0) { \
225 return -get_errno(); \
231#define DUP_ARRAY_FIELD_TO_USER(ptr, arr, arrlen, field, len, ...) \
232 if (ptr != NULL && ptr->arr != NULL) { \
233 __typeof(ptr##cpybak.arr) tmp = ptr##cpybak.arr; \
234 __typeof(ptr##bak) tmp2 = ptr##bak; \
235 ptr##cpybak.arr = ptr##arr->arr; \
236 ptr##arr->arr = tmp; \
237 ptr##bak = ptr##arr; \
238 for (size_t i = 0; i < arrlen; i++) { \
239 DUP_FIELD_TO_USER(ptr, arr[i].field, ptr->arr[i].len, ##__VA_ARGS__); \
242 ptr##arr->arr = ptr##cpybak.arr; \
243 ptr##cpybak.arr = tmp; \
246#define PointerFree(ptr) \
249 LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len)
int GetFullpath(int fd, const char *path, char **fullpath)
int UserPathCopy(const char *userPath, char **pathBuf)
void * DupUserMem(const void *ptr, size_t len, int needCopy)