1 | /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. |
2 | * |
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | * of this software and associated documentation files (the "Software"), to |
5 | * deal in the Software without restriction, including without limitation the |
6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | * sell copies of the Software, and to permit persons to whom the Software is |
8 | * furnished to do so, subject to the following conditions: |
9 | * |
10 | * The above copyright notice and this permission notice shall be included in |
11 | * all copies or substantial portions of the Software. |
12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | * IN THE SOFTWARE. |
20 | */ |
21 | |
22 | #include "linux-syscalls.h" |
23 | #include <unistd.h> |
24 | #include <signal.h> |
25 | #include <sys/syscall.h> |
26 | #include <sys/types.h> |
27 | #include <errno.h> |
28 | |
29 | #if defined(__has_feature) |
30 | # if __has_feature(memory_sanitizer) |
31 | # define MSAN_ACTIVE 1 |
32 | # include <sanitizer/msan_interface.h> |
33 | # endif |
34 | #endif |
35 | |
36 | #if defined(__i386__) |
37 | # ifndef __NR_socketcall |
38 | # define __NR_socketcall 102 |
39 | # endif |
40 | #endif |
41 | |
42 | #if defined(__arm__) |
43 | # if defined(__thumb__) || defined(__ARM_EABI__) |
44 | # define UV_SYSCALL_BASE 0 |
45 | # else |
46 | # define UV_SYSCALL_BASE 0x900000 |
47 | # endif |
48 | #endif /* __arm__ */ |
49 | |
50 | #ifndef __NR_accept4 |
51 | # if defined(__x86_64__) |
52 | # define __NR_accept4 288 |
53 | # elif defined(__i386__) |
54 | /* Nothing. Handled through socketcall(). */ |
55 | # elif defined(__arm__) |
56 | # define __NR_accept4 (UV_SYSCALL_BASE + 366) |
57 | # endif |
58 | #endif /* __NR_accept4 */ |
59 | |
60 | #ifndef __NR_eventfd |
61 | # if defined(__x86_64__) |
62 | # define __NR_eventfd 284 |
63 | # elif defined(__i386__) |
64 | # define __NR_eventfd 323 |
65 | # elif defined(__arm__) |
66 | # define __NR_eventfd (UV_SYSCALL_BASE + 351) |
67 | # endif |
68 | #endif /* __NR_eventfd */ |
69 | |
70 | #ifndef __NR_eventfd2 |
71 | # if defined(__x86_64__) |
72 | # define __NR_eventfd2 290 |
73 | # elif defined(__i386__) |
74 | # define __NR_eventfd2 328 |
75 | # elif defined(__arm__) |
76 | # define __NR_eventfd2 (UV_SYSCALL_BASE + 356) |
77 | # endif |
78 | #endif /* __NR_eventfd2 */ |
79 | |
80 | #ifndef __NR_inotify_init |
81 | # if defined(__x86_64__) |
82 | # define __NR_inotify_init 253 |
83 | # elif defined(__i386__) |
84 | # define __NR_inotify_init 291 |
85 | # elif defined(__arm__) |
86 | # define __NR_inotify_init (UV_SYSCALL_BASE + 316) |
87 | # endif |
88 | #endif /* __NR_inotify_init */ |
89 | |
90 | #ifndef __NR_inotify_init1 |
91 | # if defined(__x86_64__) |
92 | # define __NR_inotify_init1 294 |
93 | # elif defined(__i386__) |
94 | # define __NR_inotify_init1 332 |
95 | # elif defined(__arm__) |
96 | # define __NR_inotify_init1 (UV_SYSCALL_BASE + 360) |
97 | # endif |
98 | #endif /* __NR_inotify_init1 */ |
99 | |
100 | #ifndef __NR_inotify_add_watch |
101 | # if defined(__x86_64__) |
102 | # define __NR_inotify_add_watch 254 |
103 | # elif defined(__i386__) |
104 | # define __NR_inotify_add_watch 292 |
105 | # elif defined(__arm__) |
106 | # define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317) |
107 | # endif |
108 | #endif /* __NR_inotify_add_watch */ |
109 | |
110 | #ifndef __NR_inotify_rm_watch |
111 | # if defined(__x86_64__) |
112 | # define __NR_inotify_rm_watch 255 |
113 | # elif defined(__i386__) |
114 | # define __NR_inotify_rm_watch 293 |
115 | # elif defined(__arm__) |
116 | # define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318) |
117 | # endif |
118 | #endif /* __NR_inotify_rm_watch */ |
119 | |
120 | #ifndef __NR_pipe2 |
121 | # if defined(__x86_64__) |
122 | # define __NR_pipe2 293 |
123 | # elif defined(__i386__) |
124 | # define __NR_pipe2 331 |
125 | # elif defined(__arm__) |
126 | # define __NR_pipe2 (UV_SYSCALL_BASE + 359) |
127 | # endif |
128 | #endif /* __NR_pipe2 */ |
129 | |
130 | #ifndef __NR_recvmmsg |
131 | # if defined(__x86_64__) |
132 | # define __NR_recvmmsg 299 |
133 | # elif defined(__i386__) |
134 | # define __NR_recvmmsg 337 |
135 | # elif defined(__arm__) |
136 | # define __NR_recvmmsg (UV_SYSCALL_BASE + 365) |
137 | # endif |
138 | #endif /* __NR_recvmsg */ |
139 | |
140 | #ifndef __NR_sendmmsg |
141 | # if defined(__x86_64__) |
142 | # define __NR_sendmmsg 307 |
143 | # elif defined(__i386__) |
144 | # define __NR_sendmmsg 345 |
145 | # elif defined(__arm__) |
146 | # define __NR_sendmmsg (UV_SYSCALL_BASE + 374) |
147 | # endif |
148 | #endif /* __NR_sendmmsg */ |
149 | |
150 | #ifndef __NR_utimensat |
151 | # if defined(__x86_64__) |
152 | # define __NR_utimensat 280 |
153 | # elif defined(__i386__) |
154 | # define __NR_utimensat 320 |
155 | # elif defined(__arm__) |
156 | # define __NR_utimensat (UV_SYSCALL_BASE + 348) |
157 | # endif |
158 | #endif /* __NR_utimensat */ |
159 | |
160 | #ifndef __NR_preadv |
161 | # if defined(__x86_64__) |
162 | # define __NR_preadv 295 |
163 | # elif defined(__i386__) |
164 | # define __NR_preadv 333 |
165 | # elif defined(__arm__) |
166 | # define __NR_preadv (UV_SYSCALL_BASE + 361) |
167 | # endif |
168 | #endif /* __NR_preadv */ |
169 | |
170 | #ifndef __NR_pwritev |
171 | # if defined(__x86_64__) |
172 | # define __NR_pwritev 296 |
173 | # elif defined(__i386__) |
174 | # define __NR_pwritev 334 |
175 | # elif defined(__arm__) |
176 | # define __NR_pwritev (UV_SYSCALL_BASE + 362) |
177 | # endif |
178 | #endif /* __NR_pwritev */ |
179 | |
180 | #ifndef __NR_dup3 |
181 | # if defined(__x86_64__) |
182 | # define __NR_dup3 292 |
183 | # elif defined(__i386__) |
184 | # define __NR_dup3 330 |
185 | # elif defined(__arm__) |
186 | # define __NR_dup3 (UV_SYSCALL_BASE + 358) |
187 | # endif |
188 | #endif /* __NR_pwritev */ |
189 | |
190 | #ifndef __NR_statx |
191 | # if defined(__x86_64__) |
192 | # define __NR_statx 332 |
193 | # elif defined(__i386__) |
194 | # define __NR_statx 383 |
195 | # elif defined(__aarch64__) |
196 | # define __NR_statx 397 |
197 | # elif defined(__arm__) |
198 | # define __NR_statx (UV_SYSCALL_BASE + 397) |
199 | # elif defined(__ppc__) |
200 | # define __NR_statx 383 |
201 | # elif defined(__s390__) |
202 | # define __NR_statx 379 |
203 | # endif |
204 | #endif /* __NR_statx */ |
205 | |
206 | int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { |
207 | #if defined(__i386__) |
208 | unsigned long args[4]; |
209 | int r; |
210 | |
211 | args[0] = (unsigned long) fd; |
212 | args[1] = (unsigned long) addr; |
213 | args[2] = (unsigned long) addrlen; |
214 | args[3] = (unsigned long) flags; |
215 | |
216 | r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args); |
217 | |
218 | /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does |
219 | * a bad flags argument. Try to distinguish between the two cases. |
220 | */ |
221 | if (r == -1) |
222 | if (errno == EINVAL) |
223 | if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0) |
224 | errno = ENOSYS; |
225 | |
226 | return r; |
227 | #elif defined(__NR_accept4) |
228 | return syscall(__NR_accept4, fd, addr, addrlen, flags); |
229 | #else |
230 | return errno = ENOSYS, -1; |
231 | #endif |
232 | } |
233 | |
234 | |
235 | int uv__eventfd(unsigned int count) { |
236 | #if defined(__NR_eventfd) |
237 | return syscall(__NR_eventfd, count); |
238 | #else |
239 | return errno = ENOSYS, -1; |
240 | #endif |
241 | } |
242 | |
243 | |
244 | int uv__eventfd2(unsigned int count, int flags) { |
245 | #if defined(__NR_eventfd2) |
246 | return syscall(__NR_eventfd2, count, flags); |
247 | #else |
248 | return errno = ENOSYS, -1; |
249 | #endif |
250 | } |
251 | |
252 | |
253 | int uv__inotify_init(void) { |
254 | #if defined(__NR_inotify_init) |
255 | return syscall(__NR_inotify_init); |
256 | #else |
257 | return errno = ENOSYS, -1; |
258 | #endif |
259 | } |
260 | |
261 | |
262 | int uv__inotify_init1(int flags) { |
263 | #if defined(__NR_inotify_init1) |
264 | return syscall(__NR_inotify_init1, flags); |
265 | #else |
266 | return errno = ENOSYS, -1; |
267 | #endif |
268 | } |
269 | |
270 | |
271 | int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) { |
272 | #if defined(__NR_inotify_add_watch) |
273 | return syscall(__NR_inotify_add_watch, fd, path, mask); |
274 | #else |
275 | return errno = ENOSYS, -1; |
276 | #endif |
277 | } |
278 | |
279 | |
280 | int uv__inotify_rm_watch(int fd, int32_t wd) { |
281 | #if defined(__NR_inotify_rm_watch) |
282 | return syscall(__NR_inotify_rm_watch, fd, wd); |
283 | #else |
284 | return errno = ENOSYS, -1; |
285 | #endif |
286 | } |
287 | |
288 | |
289 | int uv__pipe2(int pipefd[2], int flags) { |
290 | #if defined(__NR_pipe2) |
291 | int result; |
292 | result = syscall(__NR_pipe2, pipefd, flags); |
293 | #if MSAN_ACTIVE |
294 | if (!result) |
295 | __msan_unpoison(pipefd, sizeof(int[2])); |
296 | #endif |
297 | return result; |
298 | #else |
299 | return errno = ENOSYS, -1; |
300 | #endif |
301 | } |
302 | |
303 | |
304 | int uv__sendmmsg(int fd, |
305 | struct uv__mmsghdr* mmsg, |
306 | unsigned int vlen, |
307 | unsigned int flags) { |
308 | #if defined(__NR_sendmmsg) |
309 | return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags); |
310 | #else |
311 | return errno = ENOSYS, -1; |
312 | #endif |
313 | } |
314 | |
315 | |
316 | int uv__recvmmsg(int fd, |
317 | struct uv__mmsghdr* mmsg, |
318 | unsigned int vlen, |
319 | unsigned int flags, |
320 | struct timespec* timeout) { |
321 | #if defined(__NR_recvmmsg) |
322 | return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout); |
323 | #else |
324 | return errno = ENOSYS, -1; |
325 | #endif |
326 | } |
327 | |
328 | |
329 | ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { |
330 | #if defined(__NR_preadv) |
331 | return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); |
332 | #else |
333 | return errno = ENOSYS, -1; |
334 | #endif |
335 | } |
336 | |
337 | |
338 | ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { |
339 | #if defined(__NR_pwritev) |
340 | return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); |
341 | #else |
342 | return errno = ENOSYS, -1; |
343 | #endif |
344 | } |
345 | |
346 | |
347 | int uv__dup3(int oldfd, int newfd, int flags) { |
348 | #if defined(__NR_dup3) |
349 | return syscall(__NR_dup3, oldfd, newfd, flags); |
350 | #else |
351 | return errno = ENOSYS, -1; |
352 | #endif |
353 | } |
354 | |
355 | |
356 | int uv__statx(int dirfd, |
357 | const char* path, |
358 | int flags, |
359 | unsigned int mask, |
360 | struct uv__statx* statxbuf) { |
361 | /* __NR_statx make Android box killed by SIGSYS. |
362 | * That looks like a seccomp2 sandbox filter rejecting the system call. |
363 | */ |
364 | #if defined(__NR_statx) && !defined(__ANDROID__) |
365 | return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf); |
366 | #else |
367 | return errno = ENOSYS, -1; |
368 | #endif |
369 | } |
370 | |