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 "uv.h" |
23 | #include "internal.h" |
24 | |
25 | #include <stdio.h> |
26 | #include <stdlib.h> |
27 | #include <assert.h> |
28 | #include <errno.h> |
29 | |
30 | #include <sys/types.h> |
31 | #include <sys/wait.h> |
32 | #include <unistd.h> |
33 | #include <fcntl.h> |
34 | #include <poll.h> |
35 | |
36 | #if defined(__APPLE__) && !TARGET_OS_IPHONE |
37 | # include <crt_externs.h> |
38 | # define environ (*_NSGetEnviron()) |
39 | #else |
40 | extern char **environ; |
41 | #endif |
42 | |
43 | #if defined(__linux__) || defined(__GLIBC__) |
44 | # include <grp.h> |
45 | #endif |
46 | |
47 | |
48 | static void uv__chld(uv_signal_t* handle, int signum) { |
49 | uv_process_t* process; |
50 | uv_loop_t* loop; |
51 | int exit_status; |
52 | int term_signal; |
53 | int status; |
54 | pid_t pid; |
55 | QUEUE pending; |
56 | QUEUE* q; |
57 | QUEUE* h; |
58 | |
59 | assert(signum == SIGCHLD); |
60 | |
61 | QUEUE_INIT(&pending); |
62 | loop = handle->loop; |
63 | |
64 | h = &loop->process_handles; |
65 | q = QUEUE_HEAD(h); |
66 | while (q != h) { |
67 | process = QUEUE_DATA(q, uv_process_t, queue); |
68 | q = QUEUE_NEXT(q); |
69 | |
70 | do |
71 | pid = waitpid(process->pid, &status, WNOHANG); |
72 | while (pid == -1 && errno == EINTR); |
73 | |
74 | if (pid == 0) |
75 | continue; |
76 | |
77 | if (pid == -1) { |
78 | if (errno != ECHILD) |
79 | abort(); |
80 | continue; |
81 | } |
82 | |
83 | process->status = status; |
84 | QUEUE_REMOVE(&process->queue); |
85 | QUEUE_INSERT_TAIL(&pending, &process->queue); |
86 | } |
87 | |
88 | h = &pending; |
89 | q = QUEUE_HEAD(h); |
90 | while (q != h) { |
91 | process = QUEUE_DATA(q, uv_process_t, queue); |
92 | q = QUEUE_NEXT(q); |
93 | |
94 | QUEUE_REMOVE(&process->queue); |
95 | QUEUE_INIT(&process->queue); |
96 | uv__handle_stop(process); |
97 | |
98 | if (process->exit_cb == NULL) |
99 | continue; |
100 | |
101 | exit_status = 0; |
102 | if (WIFEXITED(process->status)) |
103 | exit_status = WEXITSTATUS(process->status); |
104 | |
105 | term_signal = 0; |
106 | if (WIFSIGNALED(process->status)) |
107 | term_signal = WTERMSIG(process->status); |
108 | |
109 | process->exit_cb(process, exit_status, term_signal); |
110 | } |
111 | assert(QUEUE_EMPTY(&pending)); |
112 | } |
113 | |
114 | |
115 | int uv__make_socketpair(int fds[2], int flags) { |
116 | #if defined(__linux__) |
117 | static int no_cloexec; |
118 | |
119 | if (no_cloexec) |
120 | goto skip; |
121 | |
122 | if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0) |
123 | return 0; |
124 | |
125 | /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported. |
126 | * Anything else is a genuine error. |
127 | */ |
128 | if (errno != EINVAL) |
129 | return UV__ERR(errno); |
130 | |
131 | no_cloexec = 1; |
132 | |
133 | skip: |
134 | #endif |
135 | |
136 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) |
137 | return UV__ERR(errno); |
138 | |
139 | uv__cloexec(fds[0], 1); |
140 | uv__cloexec(fds[1], 1); |
141 | |
142 | if (flags & UV__F_NONBLOCK) { |
143 | uv__nonblock(fds[0], 1); |
144 | uv__nonblock(fds[1], 1); |
145 | } |
146 | |
147 | return 0; |
148 | } |
149 | |
150 | |
151 | int uv__make_pipe(int fds[2], int flags) { |
152 | #if defined(__linux__) |
153 | static int no_pipe2; |
154 | |
155 | if (no_pipe2) |
156 | goto skip; |
157 | |
158 | if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0) |
159 | return 0; |
160 | |
161 | if (errno != ENOSYS) |
162 | return UV__ERR(errno); |
163 | |
164 | no_pipe2 = 1; |
165 | |
166 | skip: |
167 | #endif |
168 | |
169 | if (pipe(fds)) |
170 | return UV__ERR(errno); |
171 | |
172 | uv__cloexec(fds[0], 1); |
173 | uv__cloexec(fds[1], 1); |
174 | |
175 | if (flags & UV__F_NONBLOCK) { |
176 | uv__nonblock(fds[0], 1); |
177 | uv__nonblock(fds[1], 1); |
178 | } |
179 | |
180 | return 0; |
181 | } |
182 | |
183 | |
184 | /* |
185 | * Used for initializing stdio streams like options.stdin_stream. Returns |
186 | * zero on success. See also the cleanup section in uv_spawn(). |
187 | */ |
188 | static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { |
189 | int mask; |
190 | int fd; |
191 | |
192 | mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM; |
193 | |
194 | switch (container->flags & mask) { |
195 | case UV_IGNORE: |
196 | return 0; |
197 | |
198 | case UV_CREATE_PIPE: |
199 | assert(container->data.stream != NULL); |
200 | if (container->data.stream->type != UV_NAMED_PIPE) |
201 | return UV_EINVAL; |
202 | else |
203 | return uv__make_socketpair(fds, 0); |
204 | |
205 | case UV_INHERIT_FD: |
206 | case UV_INHERIT_STREAM: |
207 | if (container->flags & UV_INHERIT_FD) |
208 | fd = container->data.fd; |
209 | else |
210 | fd = uv__stream_fd(container->data.stream); |
211 | |
212 | if (fd == -1) |
213 | return UV_EINVAL; |
214 | |
215 | fds[1] = fd; |
216 | return 0; |
217 | |
218 | default: |
219 | assert(0 && "Unexpected flags" ); |
220 | return UV_EINVAL; |
221 | } |
222 | } |
223 | |
224 | |
225 | static int uv__process_open_stream(uv_stdio_container_t* container, |
226 | int pipefds[2]) { |
227 | int flags; |
228 | int err; |
229 | |
230 | if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0) |
231 | return 0; |
232 | |
233 | err = uv__close(pipefds[1]); |
234 | if (err != 0) |
235 | abort(); |
236 | |
237 | pipefds[1] = -1; |
238 | uv__nonblock(pipefds[0], 1); |
239 | |
240 | flags = 0; |
241 | if (container->flags & UV_WRITABLE_PIPE) |
242 | flags |= UV_HANDLE_READABLE; |
243 | if (container->flags & UV_READABLE_PIPE) |
244 | flags |= UV_HANDLE_WRITABLE; |
245 | |
246 | return uv__stream_open(container->data.stream, pipefds[0], flags); |
247 | } |
248 | |
249 | |
250 | static void uv__process_close_stream(uv_stdio_container_t* container) { |
251 | if (!(container->flags & UV_CREATE_PIPE)) return; |
252 | uv__stream_close(container->data.stream); |
253 | } |
254 | |
255 | |
256 | static void uv__write_int(int fd, int val) { |
257 | ssize_t n; |
258 | |
259 | do |
260 | n = write(fd, &val, sizeof(val)); |
261 | while (n == -1 && errno == EINTR); |
262 | |
263 | if (n == -1 && errno == EPIPE) |
264 | return; /* parent process has quit */ |
265 | |
266 | assert(n == sizeof(val)); |
267 | } |
268 | |
269 | |
270 | #if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) |
271 | /* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be |
272 | * avoided. Since this isn't called on those targets, the function |
273 | * doesn't even need to be defined for them. |
274 | */ |
275 | static void uv__process_child_init(const uv_process_options_t* options, |
276 | int stdio_count, |
277 | int (*pipes)[2], |
278 | int error_fd) { |
279 | sigset_t set; |
280 | int close_fd; |
281 | int use_fd; |
282 | int err; |
283 | int fd; |
284 | int n; |
285 | |
286 | if (options->flags & UV_PROCESS_DETACHED) |
287 | setsid(); |
288 | |
289 | /* First duplicate low numbered fds, since it's not safe to duplicate them, |
290 | * they could get replaced. Example: swapping stdout and stderr; without |
291 | * this fd 2 (stderr) would be duplicated into fd 1, thus making both |
292 | * stdout and stderr go to the same fd, which was not the intention. */ |
293 | for (fd = 0; fd < stdio_count; fd++) { |
294 | use_fd = pipes[fd][1]; |
295 | if (use_fd < 0 || use_fd >= fd) |
296 | continue; |
297 | pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count); |
298 | if (pipes[fd][1] == -1) { |
299 | uv__write_int(error_fd, UV__ERR(errno)); |
300 | _exit(127); |
301 | } |
302 | } |
303 | |
304 | for (fd = 0; fd < stdio_count; fd++) { |
305 | close_fd = pipes[fd][0]; |
306 | use_fd = pipes[fd][1]; |
307 | |
308 | if (use_fd < 0) { |
309 | if (fd >= 3) |
310 | continue; |
311 | else { |
312 | /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is |
313 | * set |
314 | */ |
315 | use_fd = open("/dev/null" , fd == 0 ? O_RDONLY : O_RDWR); |
316 | close_fd = use_fd; |
317 | |
318 | if (use_fd < 0) { |
319 | uv__write_int(error_fd, UV__ERR(errno)); |
320 | _exit(127); |
321 | } |
322 | } |
323 | } |
324 | |
325 | if (fd == use_fd) |
326 | uv__cloexec_fcntl(use_fd, 0); |
327 | else |
328 | fd = dup2(use_fd, fd); |
329 | |
330 | if (fd == -1) { |
331 | uv__write_int(error_fd, UV__ERR(errno)); |
332 | _exit(127); |
333 | } |
334 | |
335 | if (fd <= 2) |
336 | uv__nonblock_fcntl(fd, 0); |
337 | |
338 | if (close_fd >= stdio_count) |
339 | uv__close(close_fd); |
340 | } |
341 | |
342 | for (fd = 0; fd < stdio_count; fd++) { |
343 | use_fd = pipes[fd][1]; |
344 | |
345 | if (use_fd >= stdio_count) |
346 | uv__close(use_fd); |
347 | } |
348 | |
349 | if (options->cwd != NULL && chdir(options->cwd)) { |
350 | uv__write_int(error_fd, UV__ERR(errno)); |
351 | _exit(127); |
352 | } |
353 | |
354 | if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) { |
355 | /* When dropping privileges from root, the `setgroups` call will |
356 | * remove any extraneous groups. If we don't call this, then |
357 | * even though our uid has dropped, we may still have groups |
358 | * that enable us to do super-user things. This will fail if we |
359 | * aren't root, so don't bother checking the return value, this |
360 | * is just done as an optimistic privilege dropping function. |
361 | */ |
362 | SAVE_ERRNO(setgroups(0, NULL)); |
363 | } |
364 | |
365 | if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) { |
366 | uv__write_int(error_fd, UV__ERR(errno)); |
367 | _exit(127); |
368 | } |
369 | |
370 | if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) { |
371 | uv__write_int(error_fd, UV__ERR(errno)); |
372 | _exit(127); |
373 | } |
374 | |
375 | if (options->env != NULL) { |
376 | environ = options->env; |
377 | } |
378 | |
379 | /* Reset signal disposition. Use a hard-coded limit because NSIG |
380 | * is not fixed on Linux: it's either 32, 34 or 64, depending on |
381 | * whether RT signals are enabled. We are not allowed to touch |
382 | * RT signal handlers, glibc uses them internally. |
383 | */ |
384 | for (n = 1; n < 32; n += 1) { |
385 | if (n == SIGKILL || n == SIGSTOP) |
386 | continue; /* Can't be changed. */ |
387 | |
388 | #if defined(__HAIKU__) |
389 | if (n == SIGKILLTHR) |
390 | continue; /* Can't be changed. */ |
391 | #endif |
392 | |
393 | if (SIG_ERR != signal(n, SIG_DFL)) |
394 | continue; |
395 | |
396 | uv__write_int(error_fd, UV__ERR(errno)); |
397 | _exit(127); |
398 | } |
399 | |
400 | /* Reset signal mask. */ |
401 | sigemptyset(&set); |
402 | err = pthread_sigmask(SIG_SETMASK, &set, NULL); |
403 | |
404 | if (err != 0) { |
405 | uv__write_int(error_fd, UV__ERR(err)); |
406 | _exit(127); |
407 | } |
408 | |
409 | execvp(options->file, options->args); |
410 | uv__write_int(error_fd, UV__ERR(errno)); |
411 | _exit(127); |
412 | } |
413 | #endif |
414 | |
415 | |
416 | int uv_spawn(uv_loop_t* loop, |
417 | uv_process_t* process, |
418 | const uv_process_options_t* options) { |
419 | #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH) |
420 | /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */ |
421 | return UV_ENOSYS; |
422 | #else |
423 | int signal_pipe[2] = { -1, -1 }; |
424 | int pipes_storage[8][2]; |
425 | int (*pipes)[2]; |
426 | int stdio_count; |
427 | ssize_t r; |
428 | pid_t pid; |
429 | int err; |
430 | int exec_errorno; |
431 | int i; |
432 | int status; |
433 | |
434 | assert(options->file != NULL); |
435 | assert(!(options->flags & ~(UV_PROCESS_DETACHED | |
436 | UV_PROCESS_SETGID | |
437 | UV_PROCESS_SETUID | |
438 | UV_PROCESS_WINDOWS_HIDE | |
439 | UV_PROCESS_WINDOWS_HIDE_CONSOLE | |
440 | UV_PROCESS_WINDOWS_HIDE_GUI | |
441 | UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); |
442 | |
443 | uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS); |
444 | QUEUE_INIT(&process->queue); |
445 | |
446 | stdio_count = options->stdio_count; |
447 | if (stdio_count < 3) |
448 | stdio_count = 3; |
449 | |
450 | err = UV_ENOMEM; |
451 | pipes = pipes_storage; |
452 | if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) |
453 | pipes = uv__malloc(stdio_count * sizeof(*pipes)); |
454 | |
455 | if (pipes == NULL) |
456 | goto error; |
457 | |
458 | for (i = 0; i < stdio_count; i++) { |
459 | pipes[i][0] = -1; |
460 | pipes[i][1] = -1; |
461 | } |
462 | |
463 | for (i = 0; i < options->stdio_count; i++) { |
464 | err = uv__process_init_stdio(options->stdio + i, pipes[i]); |
465 | if (err) |
466 | goto error; |
467 | } |
468 | |
469 | /* This pipe is used by the parent to wait until |
470 | * the child has called `execve()`. We need this |
471 | * to avoid the following race condition: |
472 | * |
473 | * if ((pid = fork()) > 0) { |
474 | * kill(pid, SIGTERM); |
475 | * } |
476 | * else if (pid == 0) { |
477 | * execve("/bin/cat", argp, envp); |
478 | * } |
479 | * |
480 | * The parent sends a signal immediately after forking. |
481 | * Since the child may not have called `execve()` yet, |
482 | * there is no telling what process receives the signal, |
483 | * our fork or /bin/cat. |
484 | * |
485 | * To avoid ambiguity, we create a pipe with both ends |
486 | * marked close-on-exec. Then, after the call to `fork()`, |
487 | * the parent polls the read end until it EOFs or errors with EPIPE. |
488 | */ |
489 | err = uv__make_pipe(signal_pipe, 0); |
490 | if (err) |
491 | goto error; |
492 | |
493 | uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); |
494 | |
495 | /* Acquire write lock to prevent opening new fds in worker threads */ |
496 | uv_rwlock_wrlock(&loop->cloexec_lock); |
497 | pid = fork(); |
498 | |
499 | if (pid == -1) { |
500 | err = UV__ERR(errno); |
501 | uv_rwlock_wrunlock(&loop->cloexec_lock); |
502 | uv__close(signal_pipe[0]); |
503 | uv__close(signal_pipe[1]); |
504 | goto error; |
505 | } |
506 | |
507 | if (pid == 0) { |
508 | uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); |
509 | abort(); |
510 | } |
511 | |
512 | /* Release lock in parent process */ |
513 | uv_rwlock_wrunlock(&loop->cloexec_lock); |
514 | uv__close(signal_pipe[1]); |
515 | |
516 | process->status = 0; |
517 | exec_errorno = 0; |
518 | do |
519 | r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno)); |
520 | while (r == -1 && errno == EINTR); |
521 | |
522 | if (r == 0) |
523 | ; /* okay, EOF */ |
524 | else if (r == sizeof(exec_errorno)) { |
525 | do |
526 | err = waitpid(pid, &status, 0); /* okay, read errorno */ |
527 | while (err == -1 && errno == EINTR); |
528 | assert(err == pid); |
529 | } else if (r == -1 && errno == EPIPE) { |
530 | do |
531 | err = waitpid(pid, &status, 0); /* okay, got EPIPE */ |
532 | while (err == -1 && errno == EINTR); |
533 | assert(err == pid); |
534 | } else |
535 | abort(); |
536 | |
537 | uv__close_nocheckstdio(signal_pipe[0]); |
538 | |
539 | for (i = 0; i < options->stdio_count; i++) { |
540 | err = uv__process_open_stream(options->stdio + i, pipes[i]); |
541 | if (err == 0) |
542 | continue; |
543 | |
544 | while (i--) |
545 | uv__process_close_stream(options->stdio + i); |
546 | |
547 | goto error; |
548 | } |
549 | |
550 | /* Only activate this handle if exec() happened successfully */ |
551 | if (exec_errorno == 0) { |
552 | QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); |
553 | uv__handle_start(process); |
554 | } |
555 | |
556 | process->pid = pid; |
557 | process->exit_cb = options->exit_cb; |
558 | |
559 | if (pipes != pipes_storage) |
560 | uv__free(pipes); |
561 | |
562 | return exec_errorno; |
563 | |
564 | error: |
565 | if (pipes != NULL) { |
566 | for (i = 0; i < stdio_count; i++) { |
567 | if (i < options->stdio_count) |
568 | if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM)) |
569 | continue; |
570 | if (pipes[i][0] != -1) |
571 | uv__close_nocheckstdio(pipes[i][0]); |
572 | if (pipes[i][1] != -1) |
573 | uv__close_nocheckstdio(pipes[i][1]); |
574 | } |
575 | |
576 | if (pipes != pipes_storage) |
577 | uv__free(pipes); |
578 | } |
579 | |
580 | return err; |
581 | #endif |
582 | } |
583 | |
584 | |
585 | int uv_process_kill(uv_process_t* process, int signum) { |
586 | return uv_kill(process->pid, signum); |
587 | } |
588 | |
589 | |
590 | int uv_kill(int pid, int signum) { |
591 | if (kill(pid, signum)) |
592 | return UV__ERR(errno); |
593 | else |
594 | return 0; |
595 | } |
596 | |
597 | |
598 | void uv__process_close(uv_process_t* handle) { |
599 | QUEUE_REMOVE(&handle->queue); |
600 | uv__handle_stop(handle); |
601 | if (QUEUE_EMPTY(&handle->loop->process_handles)) |
602 | uv_signal_stop(&handle->loop->child_watcher); |
603 | } |
604 | |