更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
syscall_pub.h
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31#ifndef _SYSCALL_PUB_H
32#define _SYSCALL_PUB_H
33
34#include <stdlib.h>
35#include "los_memory.h"
36#include "los_vm_lock.h"
37#include "los_vm_map.h"
38#include "user_copy.h"
39#include "fs/fs.h"
40#include "fcntl.h"
42
43extern int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len);
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);
47
48#define CHECK_ASPACE(ptr, len, ...) \
49 do { \
50 if (ptr != NULL && len != 0) { \
51 if (!LOS_IsUserAddressRange((VADDR_T)(UINTPTR)ptr, len)) { \
52 set_errno(EFAULT); \
53 __VA_ARGS__; \
54 return -get_errno(); \
55 } \
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); \
60 set_errno(EFAULT); \
61 __VA_ARGS__; \
62 return -get_errno(); \
63 } \
64 (VOID)LOS_MuxRelease(&__aspace->regionMux); \
65 } \
66 } while (0)
67
68#define LEN(ptr) ((ptr) ? *(ptr) : 0)
69
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); \
74 if (ptr == NULL) { \
75 ptr = ptr##bak; \
76 __VA_ARGS__; \
77 return -get_errno(); \
78 } \
79 }
80
81/*
82DUP_FROM_USER(ptr, size, ...) can not deal with "char *";
83Please deal with the "char *" by function:UserPathCopy.
84*/
85#define DUP_FROM_USER(ptr, size, ...) \
86 DUP_FROM_USER_(ptr, size, 1, ##__VA_ARGS__)
87
88#define DUP_FROM_USER_NOCOPY(ptr, size, ...) \
89 DUP_FROM_USER_(ptr, size, 0, ##__VA_ARGS__)
90
91#define DUP_TO_USER(ptr, size, ...) \
92 do { \
93 if (ptr != NULL && (size) != 0) { \
94 if (LOS_ArchCopyToUser(ptr##bak, ptr, size) != 0) { \
95 set_errno(EFAULT); \
96 __VA_ARGS__; \
97 return -get_errno(); \
98 } \
99 } \
100 } while (0)
101
102#define FREE_DUP(ptr) \
103 do { \
104 if (ptr != ptr##bak) { \
105 LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \
106 ptr = ptr##bak; \
107 } \
108 } while (0)
109
110#define CPY_FROM_USER(ptr) \
111 __typeof(*ptr) ptr##cpy = {0}, *ptr##bak = ptr; \
112 if (ptr != NULL) { \
113 if (LOS_ArchCopyFromUser((void*)&ptr##cpy, ptr##bak, sizeof(*ptr##bak)) != 0) { \
114 set_errno(EFAULT); \
115 return -get_errno(); \
116 } \
117 ptr = &ptr##cpy; \
118 }
119
120#define CPY_TO_USER(ptr, ...) \
121 if (ptr != NULL) { \
122 if (LOS_ArchCopyToUser(ptr##bak, ptr, sizeof(*ptr)) != 0) { \
123 set_errno(EFAULT); \
124 __VA_ARGS__; \
125 return -get_errno(); \
126 } \
127 }
128
129/** Macros for sendmsg and recvmsg */
130
131#define CONST_CAST(ptr) ((__typeof(ptr##_NONCONST))ptr)
132
133#define CHECK_FIELD_ASPACE(ptr, field, len) \
134 do { \
135 if (ptr != NULL) { \
136 CHECK_ASPACE(ptr->field, len); \
137 } \
138 } while (0)
139
140#define CHECK_ARRAY_FIELD_ASPACE(ptr, arr, arrlen, field, len, ...) \
141 do { \
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__); \
145 } \
146 } \
147 } while (0)
148
149#define DUP_FIELD_FROM_USER_(ptr, field, size, copy, ...) \
150 do { \
151 if (ptr != NULL && ptr->field != NULL && (size) != 0) { \
152 CONST_CAST(ptr)->field = DupUserMem(ptr->field, size, copy); \
153 if (ptr->field == NULL) { \
154 __VA_ARGS__; \
155 return -get_errno(); \
156 } \
157 } \
158 } while (0)
159
160#define DUP_FIELD_FROM_USER(ptr, field, size, ...) \
161 DUP_FIELD_FROM_USER_(ptr, field, size, 1, ##__VA_ARGS__)
162
163#define DUP_FIELD_FROM_USER_NOCOPY(ptr, field, size, ...) \
164 DUP_FIELD_FROM_USER_(ptr, field, size, 0, ##__VA_ARGS__)
165
166/* backup the arr to ptr##arr */
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) { \
172 size_t i = 0; \
173 for (; i < arrlen; i++) { \
174 DUP_FIELD_FROM_USER##ext(ptr, arr[i].field, ptr->arr[i].len, break); \
175 } \
176 if (i != arrlen) { \
177 FREE_DUP_ARRAY_FIELD(ptr, arr, i, field); \
178 __VA_ARGS__; \
179 return -get_errno(); \
180 } \
181 }
182
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__)
185
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__)
188
189#define FREE_DUP_FIELD(ptr, field) \
190 do { \
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; \
194 } \
195 } while (0)
196
197/* use and free the backuped arr in ptr##arr */
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); \
204 } \
205 ptr##cpybak.arr = tmp; \
206 } \
207 FREE_DUP_FIELD(ptr##arr, arr);
208
209#define CPY_FROM_CONST_USER(NonConstType, ptr) \
210 CPY_FROM_USER(ptr); \
211 NonConstType *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy; \
212 (void)ptr##bak;
213
214#define CPY_FROM_NONCONST_USER(ptr) \
215 CPY_FROM_USER(ptr); \
216 __typeof(*ptr) *ptr##_NONCONST = NULL, ptr##cpybak = ptr##cpy;
217
218#define DUP_FIELD_TO_USER(ptr, field, size, ...) \
219 do { \
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) { \
223 set_errno(EFAULT); \
224 __VA_ARGS__; \
225 return -get_errno(); \
226 } \
227 } \
228 } while (0)
229
230/* use the backuped arr from ptr##arr */
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__); \
240 } \
241 ptr##bak = tmp2; \
242 ptr##arr->arr = ptr##cpybak.arr; \
243 ptr##cpybak.arr = tmp; \
244 }
245
246#define PointerFree(ptr) \
247 do { \
248 if (ptr != NULL) { \
249 LOS_MemFree(OS_SYS_MEM_ADDR, (void*)ptr); \
250 } \
251 } while (0)
252#endif
unsigned long VADDR_T
Definition: los_typedef.h:208
虚拟空间,每个进程都有一个属于自己的虚拟内存地址空间
Definition: los_vm_map.h:146
int CheckRegion(const LosVmSpace *space, VADDR_T ptr, size_t len)
Definition: syscall_pub.c:33
int GetFullpath(int fd, const char *path, char **fullpath)
Definition: syscall_pub.c:64
int UserPathCopy(const char *userPath, char **pathBuf)
Definition: syscall_pub.c:105
void * DupUserMem(const void *ptr, size_t len, int needCopy)
Definition: syscall_pub.c:46