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 | * Used for initializing stdio streams like options.stdin_stream. Returns |
116 | * zero on success. See also the cleanup section in uv_spawn(). |
117 | */ |
118 | static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { |
119 | int mask; |
120 | int fd; |
121 | |
122 | mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM; |
123 | |
124 | switch (container->flags & mask) { |
125 | case UV_IGNORE: |
126 | return 0; |
127 | |
128 | case UV_CREATE_PIPE: |
129 | assert(container->data.stream != NULL); |
130 | if (container->data.stream->type != UV_NAMED_PIPE) |
131 | return UV_EINVAL; |
132 | else |
133 | return uv_socketpair(SOCK_STREAM, 0, fds, 0, 0); |
134 | |
135 | case UV_INHERIT_FD: |
136 | case UV_INHERIT_STREAM: |
137 | if (container->flags & UV_INHERIT_FD) |
138 | fd = container->data.fd; |
139 | else |
140 | fd = uv__stream_fd(container->data.stream); |
141 | |
142 | if (fd == -1) |
143 | return UV_EINVAL; |
144 | |
145 | fds[1] = fd; |
146 | return 0; |
147 | |
148 | default: |
149 | assert(0 && "Unexpected flags" ); |
150 | return UV_EINVAL; |
151 | } |
152 | } |
153 | |
154 | |
155 | static int uv__process_open_stream(uv_stdio_container_t* container, |
156 | int pipefds[2]) { |
157 | int flags; |
158 | int err; |
159 | |
160 | if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0) |
161 | return 0; |
162 | |
163 | err = uv__close(pipefds[1]); |
164 | if (err != 0) |
165 | abort(); |
166 | |
167 | pipefds[1] = -1; |
168 | uv__nonblock(pipefds[0], 1); |
169 | |
170 | flags = 0; |
171 | if (container->flags & UV_WRITABLE_PIPE) |
172 | flags |= UV_HANDLE_READABLE; |
173 | if (container->flags & UV_READABLE_PIPE) |
174 | flags |= UV_HANDLE_WRITABLE; |
175 | |
176 | return uv__stream_open(container->data.stream, pipefds[0], flags); |
177 | } |
178 | |
179 | |
180 | static void uv__process_close_stream(uv_stdio_container_t* container) { |
181 | if (!(container->flags & UV_CREATE_PIPE)) return; |
182 | uv__stream_close(container->data.stream); |
183 | } |
184 | |
185 | |
186 | static void uv__write_int(int fd, int val) { |
187 | ssize_t n; |
188 | |
189 | do |
190 | n = write(fd, &val, sizeof(val)); |
191 | while (n == -1 && errno == EINTR); |
192 | |
193 | if (n == -1 && errno == EPIPE) |
194 | return; /* parent process has quit */ |
195 | |
196 | assert(n == sizeof(val)); |
197 | } |
198 | |
199 | |
200 | #if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) |
201 | /* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be |
202 | * avoided. Since this isn't called on those targets, the function |
203 | * doesn't even need to be defined for them. |
204 | */ |
205 | static void uv__process_child_init(const uv_process_options_t* options, |
206 | int stdio_count, |
207 | int (*pipes)[2], |
208 | int error_fd) { |
209 | sigset_t set; |
210 | int close_fd; |
211 | int use_fd; |
212 | int err; |
213 | int fd; |
214 | int n; |
215 | |
216 | if (options->flags & UV_PROCESS_DETACHED) |
217 | setsid(); |
218 | |
219 | /* First duplicate low numbered fds, since it's not safe to duplicate them, |
220 | * they could get replaced. Example: swapping stdout and stderr; without |
221 | * this fd 2 (stderr) would be duplicated into fd 1, thus making both |
222 | * stdout and stderr go to the same fd, which was not the intention. */ |
223 | for (fd = 0; fd < stdio_count; fd++) { |
224 | use_fd = pipes[fd][1]; |
225 | if (use_fd < 0 || use_fd >= fd) |
226 | continue; |
227 | pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count); |
228 | if (pipes[fd][1] == -1) { |
229 | uv__write_int(error_fd, UV__ERR(errno)); |
230 | _exit(127); |
231 | } |
232 | } |
233 | |
234 | for (fd = 0; fd < stdio_count; fd++) { |
235 | close_fd = pipes[fd][0]; |
236 | use_fd = pipes[fd][1]; |
237 | |
238 | if (use_fd < 0) { |
239 | if (fd >= 3) |
240 | continue; |
241 | else { |
242 | /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is |
243 | * set |
244 | */ |
245 | use_fd = open("/dev/null" , fd == 0 ? O_RDONLY : O_RDWR); |
246 | close_fd = use_fd; |
247 | |
248 | if (use_fd < 0) { |
249 | uv__write_int(error_fd, UV__ERR(errno)); |
250 | _exit(127); |
251 | } |
252 | } |
253 | } |
254 | |
255 | if (fd == use_fd) |
256 | uv__cloexec_fcntl(use_fd, 0); |
257 | else |
258 | fd = dup2(use_fd, fd); |
259 | |
260 | if (fd == -1) { |
261 | uv__write_int(error_fd, UV__ERR(errno)); |
262 | _exit(127); |
263 | } |
264 | |
265 | if (fd <= 2) |
266 | uv__nonblock_fcntl(fd, 0); |
267 | |
268 | if (close_fd >= stdio_count) |
269 | uv__close(close_fd); |
270 | } |
271 | |
272 | for (fd = 0; fd < stdio_count; fd++) { |
273 | use_fd = pipes[fd][1]; |
274 | |
275 | if (use_fd >= stdio_count) |
276 | uv__close(use_fd); |
277 | } |
278 | |
279 | if (options->cwd != NULL && chdir(options->cwd)) { |
280 | uv__write_int(error_fd, UV__ERR(errno)); |
281 | _exit(127); |
282 | } |
283 | |
284 | if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) { |
285 | /* When dropping privileges from root, the `setgroups` call will |
286 | * remove any extraneous groups. If we don't call this, then |
287 | * even though our uid has dropped, we may still have groups |
288 | * that enable us to do super-user things. This will fail if we |
289 | * aren't root, so don't bother checking the return value, this |
290 | * is just done as an optimistic privilege dropping function. |
291 | */ |
292 | SAVE_ERRNO(setgroups(0, NULL)); |
293 | } |
294 | |
295 | if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) { |
296 | uv__write_int(error_fd, UV__ERR(errno)); |
297 | _exit(127); |
298 | } |
299 | |
300 | if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) { |
301 | uv__write_int(error_fd, UV__ERR(errno)); |
302 | _exit(127); |
303 | } |
304 | |
305 | if (options->env != NULL) { |
306 | environ = options->env; |
307 | } |
308 | |
309 | /* Reset signal disposition. Use a hard-coded limit because NSIG |
310 | * is not fixed on Linux: it's either 32, 34 or 64, depending on |
311 | * whether RT signals are enabled. We are not allowed to touch |
312 | * RT signal handlers, glibc uses them internally. |
313 | */ |
314 | for (n = 1; n < 32; n += 1) { |
315 | if (n == SIGKILL || n == SIGSTOP) |
316 | continue; /* Can't be changed. */ |
317 | |
318 | #if defined(__HAIKU__) |
319 | if (n == SIGKILLTHR) |
320 | continue; /* Can't be changed. */ |
321 | #endif |
322 | |
323 | if (SIG_ERR != signal(n, SIG_DFL)) |
324 | continue; |
325 | |
326 | uv__write_int(error_fd, UV__ERR(errno)); |
327 | _exit(127); |
328 | } |
329 | |
330 | /* Reset signal mask. */ |
331 | sigemptyset(&set); |
332 | err = pthread_sigmask(SIG_SETMASK, &set, NULL); |
333 | |
334 | if (err != 0) { |
335 | uv__write_int(error_fd, UV__ERR(err)); |
336 | _exit(127); |
337 | } |
338 | |
339 | execvp(options->file, options->args); |
340 | uv__write_int(error_fd, UV__ERR(errno)); |
341 | _exit(127); |
342 | } |
343 | #endif |
344 | |
345 | |
346 | int uv_spawn(uv_loop_t* loop, |
347 | uv_process_t* process, |
348 | const uv_process_options_t* options) { |
349 | #if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH) |
350 | /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */ |
351 | return UV_ENOSYS; |
352 | #else |
353 | int signal_pipe[2] = { -1, -1 }; |
354 | int pipes_storage[8][2]; |
355 | int (*pipes)[2]; |
356 | int stdio_count; |
357 | ssize_t r; |
358 | pid_t pid; |
359 | int err; |
360 | int exec_errorno; |
361 | int i; |
362 | int status; |
363 | |
364 | assert(options->file != NULL); |
365 | assert(!(options->flags & ~(UV_PROCESS_DETACHED | |
366 | UV_PROCESS_SETGID | |
367 | UV_PROCESS_SETUID | |
368 | UV_PROCESS_WINDOWS_HIDE | |
369 | UV_PROCESS_WINDOWS_HIDE_CONSOLE | |
370 | UV_PROCESS_WINDOWS_HIDE_GUI | |
371 | UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); |
372 | |
373 | uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS); |
374 | QUEUE_INIT(&process->queue); |
375 | |
376 | stdio_count = options->stdio_count; |
377 | if (stdio_count < 3) |
378 | stdio_count = 3; |
379 | |
380 | err = UV_ENOMEM; |
381 | pipes = pipes_storage; |
382 | if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) |
383 | pipes = uv__malloc(stdio_count * sizeof(*pipes)); |
384 | |
385 | if (pipes == NULL) |
386 | goto error; |
387 | |
388 | for (i = 0; i < stdio_count; i++) { |
389 | pipes[i][0] = -1; |
390 | pipes[i][1] = -1; |
391 | } |
392 | |
393 | for (i = 0; i < options->stdio_count; i++) { |
394 | err = uv__process_init_stdio(options->stdio + i, pipes[i]); |
395 | if (err) |
396 | goto error; |
397 | } |
398 | |
399 | /* This pipe is used by the parent to wait until |
400 | * the child has called `execve()`. We need this |
401 | * to avoid the following race condition: |
402 | * |
403 | * if ((pid = fork()) > 0) { |
404 | * kill(pid, SIGTERM); |
405 | * } |
406 | * else if (pid == 0) { |
407 | * execve("/bin/cat", argp, envp); |
408 | * } |
409 | * |
410 | * The parent sends a signal immediately after forking. |
411 | * Since the child may not have called `execve()` yet, |
412 | * there is no telling what process receives the signal, |
413 | * our fork or /bin/cat. |
414 | * |
415 | * To avoid ambiguity, we create a pipe with both ends |
416 | * marked close-on-exec. Then, after the call to `fork()`, |
417 | * the parent polls the read end until it EOFs or errors with EPIPE. |
418 | */ |
419 | err = uv__make_pipe(signal_pipe, 0); |
420 | if (err) |
421 | goto error; |
422 | |
423 | uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); |
424 | |
425 | /* Acquire write lock to prevent opening new fds in worker threads */ |
426 | uv_rwlock_wrlock(&loop->cloexec_lock); |
427 | pid = fork(); |
428 | |
429 | if (pid == -1) { |
430 | err = UV__ERR(errno); |
431 | uv_rwlock_wrunlock(&loop->cloexec_lock); |
432 | uv__close(signal_pipe[0]); |
433 | uv__close(signal_pipe[1]); |
434 | goto error; |
435 | } |
436 | |
437 | if (pid == 0) { |
438 | uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); |
439 | abort(); |
440 | } |
441 | |
442 | /* Release lock in parent process */ |
443 | uv_rwlock_wrunlock(&loop->cloexec_lock); |
444 | uv__close(signal_pipe[1]); |
445 | |
446 | process->status = 0; |
447 | exec_errorno = 0; |
448 | do |
449 | r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno)); |
450 | while (r == -1 && errno == EINTR); |
451 | |
452 | if (r == 0) |
453 | ; /* okay, EOF */ |
454 | else if (r == sizeof(exec_errorno)) { |
455 | do |
456 | err = waitpid(pid, &status, 0); /* okay, read errorno */ |
457 | while (err == -1 && errno == EINTR); |
458 | assert(err == pid); |
459 | } else if (r == -1 && errno == EPIPE) { |
460 | do |
461 | err = waitpid(pid, &status, 0); /* okay, got EPIPE */ |
462 | while (err == -1 && errno == EINTR); |
463 | assert(err == pid); |
464 | } else |
465 | abort(); |
466 | |
467 | uv__close_nocheckstdio(signal_pipe[0]); |
468 | |
469 | for (i = 0; i < options->stdio_count; i++) { |
470 | err = uv__process_open_stream(options->stdio + i, pipes[i]); |
471 | if (err == 0) |
472 | continue; |
473 | |
474 | while (i--) |
475 | uv__process_close_stream(options->stdio + i); |
476 | |
477 | goto error; |
478 | } |
479 | |
480 | /* Only activate this handle if exec() happened successfully */ |
481 | if (exec_errorno == 0) { |
482 | QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); |
483 | uv__handle_start(process); |
484 | } |
485 | |
486 | process->pid = pid; |
487 | process->exit_cb = options->exit_cb; |
488 | |
489 | if (pipes != pipes_storage) |
490 | uv__free(pipes); |
491 | |
492 | return exec_errorno; |
493 | |
494 | error: |
495 | if (pipes != NULL) { |
496 | for (i = 0; i < stdio_count; i++) { |
497 | if (i < options->stdio_count) |
498 | if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM)) |
499 | continue; |
500 | if (pipes[i][0] != -1) |
501 | uv__close_nocheckstdio(pipes[i][0]); |
502 | if (pipes[i][1] != -1) |
503 | uv__close_nocheckstdio(pipes[i][1]); |
504 | } |
505 | |
506 | if (pipes != pipes_storage) |
507 | uv__free(pipes); |
508 | } |
509 | |
510 | return err; |
511 | #endif |
512 | } |
513 | |
514 | |
515 | int uv_process_kill(uv_process_t* process, int signum) { |
516 | return uv_kill(process->pid, signum); |
517 | } |
518 | |
519 | |
520 | int uv_kill(int pid, int signum) { |
521 | if (kill(pid, signum)) |
522 | return UV__ERR(errno); |
523 | else |
524 | return 0; |
525 | } |
526 | |
527 | |
528 | void uv__process_close(uv_process_t* handle) { |
529 | QUEUE_REMOVE(&handle->queue); |
530 | uv__handle_stop(handle); |
531 | if (QUEUE_EMPTY(&handle->loop->process_handles)) |
532 | uv_signal_stop(&handle->loop->child_watcher); |
533 | } |
534 | |