1 | /* |
2 | * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #include <dirent.h> |
27 | #include <errno.h> |
28 | #include <fcntl.h> |
29 | #include <stdlib.h> |
30 | #include <string.h> |
31 | #include <unistd.h> |
32 | #include <limits.h> |
33 | |
34 | #include "childproc.h" |
35 | |
36 | |
37 | ssize_t |
38 | restartableWrite(int fd, const void *buf, size_t count) |
39 | { |
40 | ssize_t result; |
41 | RESTARTABLE(write(fd, buf, count), result); |
42 | return result; |
43 | } |
44 | |
45 | int |
46 | restartableDup2(int fd_from, int fd_to) |
47 | { |
48 | int err; |
49 | RESTARTABLE(dup2(fd_from, fd_to), err); |
50 | return err; |
51 | } |
52 | |
53 | int |
54 | closeSafely(int fd) |
55 | { |
56 | return (fd == -1) ? 0 : close(fd); |
57 | } |
58 | |
59 | int |
60 | isAsciiDigit(char c) |
61 | { |
62 | return c >= '0' && c <= '9'; |
63 | } |
64 | |
65 | #if defined(_AIX) |
66 | /* AIX does not understand '/proc/self' - it requires the real process ID */ |
67 | #define FD_DIR aix_fd_dir |
68 | #define DIR DIR64 |
69 | #define dirent dirent64 |
70 | #define opendir opendir64 |
71 | #define readdir readdir64 |
72 | #define closedir closedir64 |
73 | #elif defined(_ALLBSD_SOURCE) |
74 | #define FD_DIR "/dev/fd" |
75 | #else |
76 | #define FD_DIR "/proc/self/fd" |
77 | #endif |
78 | |
79 | int |
80 | closeDescriptors(void) |
81 | { |
82 | DIR *dp; |
83 | struct dirent *dirp; |
84 | int from_fd = FAIL_FILENO + 1; |
85 | |
86 | /* We're trying to close all file descriptors, but opendir() might |
87 | * itself be implemented using a file descriptor, and we certainly |
88 | * don't want to close that while it's in use. We assume that if |
89 | * opendir() is implemented using a file descriptor, then it uses |
90 | * the lowest numbered file descriptor, just like open(). So we |
91 | * close a couple explicitly. */ |
92 | |
93 | close(from_fd); /* for possible use by opendir() */ |
94 | close(from_fd + 1); /* another one for good luck */ |
95 | |
96 | #if defined(_AIX) |
97 | /* AIX does not understand '/proc/self' - it requires the real process ID */ |
98 | char aix_fd_dir[32]; /* the pid has at most 19 digits */ |
99 | snprintf(aix_fd_dir, 32, "/proc/%d/fd" , getpid()); |
100 | #endif |
101 | |
102 | if ((dp = opendir(FD_DIR)) == NULL) |
103 | return 0; |
104 | |
105 | while ((dirp = readdir(dp)) != NULL) { |
106 | int fd; |
107 | if (isAsciiDigit(dirp->d_name[0]) && |
108 | (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) |
109 | close(fd); |
110 | } |
111 | |
112 | closedir(dp); |
113 | |
114 | return 1; |
115 | } |
116 | |
117 | int |
118 | moveDescriptor(int fd_from, int fd_to) |
119 | { |
120 | if (fd_from != fd_to) { |
121 | if ((restartableDup2(fd_from, fd_to) == -1) || |
122 | (close(fd_from) == -1)) |
123 | return -1; |
124 | } |
125 | return 0; |
126 | } |
127 | |
128 | int |
129 | magicNumber() { |
130 | return 43110; |
131 | } |
132 | |
133 | /* |
134 | * Reads nbyte bytes from file descriptor fd into buf, |
135 | * The read operation is retried in case of EINTR or partial reads. |
136 | * |
137 | * Returns number of bytes read (normally nbyte, but may be less in |
138 | * case of EOF). In case of read errors, returns -1 and sets errno. |
139 | */ |
140 | ssize_t |
141 | readFully(int fd, void *buf, size_t nbyte) |
142 | { |
143 | ssize_t remaining = nbyte; |
144 | for (;;) { |
145 | ssize_t n = read(fd, buf, remaining); |
146 | if (n == 0) { |
147 | return nbyte - remaining; |
148 | } else if (n > 0) { |
149 | remaining -= n; |
150 | if (remaining <= 0) |
151 | return nbyte; |
152 | /* We were interrupted in the middle of reading the bytes. |
153 | * Unlikely, but possible. */ |
154 | buf = (void *) (((char *)buf) + n); |
155 | } else if (errno == EINTR) { |
156 | /* Strange signals like SIGJVM1 are possible at any time. |
157 | * See http://www.dreamsongs.com/WorseIsBetter.html */ |
158 | } else { |
159 | return -1; |
160 | } |
161 | } |
162 | } |
163 | |
164 | void |
165 | initVectorFromBlock(const char**vector, const char* block, int count) |
166 | { |
167 | int i; |
168 | const char *p; |
169 | for (i = 0, p = block; i < count; i++) { |
170 | /* Invariant: p always points to the start of a C string. */ |
171 | vector[i] = p; |
172 | while (*(p++)); |
173 | } |
174 | vector[count] = NULL; |
175 | } |
176 | |
177 | /** |
178 | * Exec FILE as a traditional Bourne shell script (i.e. one without #!). |
179 | * If we could do it over again, we would probably not support such an ancient |
180 | * misfeature, but compatibility wins over sanity. The original support for |
181 | * this was imported accidentally from execvp(). |
182 | */ |
183 | void |
184 | execve_as_traditional_shell_script(const char *file, |
185 | const char *argv[], |
186 | const char *const envp[]) |
187 | { |
188 | /* Use the extra word of space provided for us in argv by caller. */ |
189 | const char *argv0 = argv[0]; |
190 | const char *const *end = argv; |
191 | while (*end != NULL) |
192 | ++end; |
193 | memmove(argv+2, argv+1, (end-argv) * sizeof(*end)); |
194 | argv[0] = "/bin/sh" ; |
195 | argv[1] = file; |
196 | execve(argv[0], (char **) argv, (char **) envp); |
197 | /* Can't even exec /bin/sh? Big trouble, but let's soldier on... */ |
198 | memmove(argv+1, argv+2, (end-argv) * sizeof(*end)); |
199 | argv[0] = argv0; |
200 | } |
201 | |
202 | /** |
203 | * Like execve(2), except that in case of ENOEXEC, FILE is assumed to |
204 | * be a shell script and the system default shell is invoked to run it. |
205 | */ |
206 | void |
207 | execve_with_shell_fallback(int mode, const char *file, |
208 | const char *argv[], |
209 | const char *const envp[]) |
210 | { |
211 | if (mode == MODE_CLONE || mode == MODE_VFORK) { |
212 | /* shared address space; be very careful. */ |
213 | execve(file, (char **) argv, (char **) envp); |
214 | if (errno == ENOEXEC) |
215 | execve_as_traditional_shell_script(file, argv, envp); |
216 | } else { |
217 | /* unshared address space; we can mutate environ. */ |
218 | environ = (char **) envp; |
219 | execvp(file, (char **) argv); |
220 | } |
221 | } |
222 | |
223 | /** |
224 | * 'execvpe' should have been included in the Unix standards, |
225 | * and is a GNU extension in glibc 2.10. |
226 | * |
227 | * JDK_execvpe is identical to execvp, except that the child environment is |
228 | * specified via the 3rd argument instead of being inherited from environ. |
229 | */ |
230 | void |
231 | JDK_execvpe(int mode, const char *file, |
232 | const char *argv[], |
233 | const char *const envp[]) |
234 | { |
235 | if (envp == NULL || (char **) envp == environ) { |
236 | execvp(file, (char **) argv); |
237 | return; |
238 | } |
239 | |
240 | if (*file == '\0') { |
241 | errno = ENOENT; |
242 | return; |
243 | } |
244 | |
245 | if (strchr(file, '/') != NULL) { |
246 | execve_with_shell_fallback(mode, file, argv, envp); |
247 | } else { |
248 | /* We must search PATH (parent's, not child's) */ |
249 | char expanded_file[PATH_MAX]; |
250 | int filelen = strlen(file); |
251 | int sticky_errno = 0; |
252 | const char * const * dirs; |
253 | for (dirs = parentPathv; *dirs; dirs++) { |
254 | const char * dir = *dirs; |
255 | int dirlen = strlen(dir); |
256 | if (filelen + dirlen + 2 >= PATH_MAX) { |
257 | errno = ENAMETOOLONG; |
258 | continue; |
259 | } |
260 | memcpy(expanded_file, dir, dirlen); |
261 | if (expanded_file[dirlen - 1] != '/') |
262 | expanded_file[dirlen++] = '/'; |
263 | memcpy(expanded_file + dirlen, file, filelen); |
264 | expanded_file[dirlen + filelen] = '\0'; |
265 | execve_with_shell_fallback(mode, expanded_file, argv, envp); |
266 | /* There are 3 responses to various classes of errno: |
267 | * return immediately, continue (especially for ENOENT), |
268 | * or continue with "sticky" errno. |
269 | * |
270 | * From exec(3): |
271 | * |
272 | * If permission is denied for a file (the attempted |
273 | * execve returned EACCES), these functions will continue |
274 | * searching the rest of the search path. If no other |
275 | * file is found, however, they will return with the |
276 | * global variable errno set to EACCES. |
277 | */ |
278 | switch (errno) { |
279 | case EACCES: |
280 | sticky_errno = errno; |
281 | /* FALLTHRU */ |
282 | case ENOENT: |
283 | case ENOTDIR: |
284 | #ifdef ELOOP |
285 | case ELOOP: |
286 | #endif |
287 | #ifdef ESTALE |
288 | case ESTALE: |
289 | #endif |
290 | #ifdef ENODEV |
291 | case ENODEV: |
292 | #endif |
293 | #ifdef ETIMEDOUT |
294 | case ETIMEDOUT: |
295 | #endif |
296 | break; /* Try other directories in PATH */ |
297 | default: |
298 | return; |
299 | } |
300 | } |
301 | if (sticky_errno != 0) |
302 | errno = sticky_errno; |
303 | } |
304 | } |
305 | |
306 | /** |
307 | * Child process after a successful fork(). |
308 | * This function must not return, and must be prepared for either all |
309 | * of its address space to be shared with its parent, or to be a copy. |
310 | * It must not modify global variables such as "environ". |
311 | */ |
312 | int |
313 | childProcess(void *arg) |
314 | { |
315 | const ChildStuff* p = (const ChildStuff*) arg; |
316 | int fail_pipe_fd = p->fail[1]; |
317 | |
318 | if (p->sendAlivePing) { |
319 | /* Child shall signal aliveness to parent at the very first |
320 | * moment. */ |
321 | int code = CHILD_IS_ALIVE; |
322 | restartableWrite(fail_pipe_fd, &code, sizeof(code)); |
323 | } |
324 | |
325 | /* Close the parent sides of the pipes. |
326 | Closing pipe fds here is redundant, since closeDescriptors() |
327 | would do it anyways, but a little paranoia is a good thing. */ |
328 | if ((closeSafely(p->in[1]) == -1) || |
329 | (closeSafely(p->out[0]) == -1) || |
330 | (closeSafely(p->err[0]) == -1) || |
331 | (closeSafely(p->childenv[0]) == -1) || |
332 | (closeSafely(p->childenv[1]) == -1) || |
333 | (closeSafely(p->fail[0]) == -1)) |
334 | goto WhyCantJohnnyExec; |
335 | |
336 | /* Give the child sides of the pipes the right fileno's. */ |
337 | /* Note: it is possible for in[0] == 0 */ |
338 | if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], |
339 | STDIN_FILENO) == -1) || |
340 | (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], |
341 | STDOUT_FILENO) == -1)) |
342 | goto WhyCantJohnnyExec; |
343 | |
344 | if (p->redirectErrorStream) { |
345 | if ((closeSafely(p->err[1]) == -1) || |
346 | (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) |
347 | goto WhyCantJohnnyExec; |
348 | } else { |
349 | if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], |
350 | STDERR_FILENO) == -1) |
351 | goto WhyCantJohnnyExec; |
352 | } |
353 | |
354 | if (moveDescriptor(fail_pipe_fd, FAIL_FILENO) == -1) |
355 | goto WhyCantJohnnyExec; |
356 | |
357 | /* We moved the fail pipe fd */ |
358 | fail_pipe_fd = FAIL_FILENO; |
359 | |
360 | /* close everything */ |
361 | if (closeDescriptors() == 0) { /* failed, close the old way */ |
362 | int max_fd = (int)sysconf(_SC_OPEN_MAX); |
363 | int fd; |
364 | for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) |
365 | if (close(fd) == -1 && errno != EBADF) |
366 | goto WhyCantJohnnyExec; |
367 | } |
368 | |
369 | /* change to the new working directory */ |
370 | if (p->pdir != NULL && chdir(p->pdir) < 0) |
371 | goto WhyCantJohnnyExec; |
372 | |
373 | if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) |
374 | goto WhyCantJohnnyExec; |
375 | |
376 | JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv); |
377 | |
378 | WhyCantJohnnyExec: |
379 | /* We used to go to an awful lot of trouble to predict whether the |
380 | * child would fail, but there is no reliable way to predict the |
381 | * success of an operation without *trying* it, and there's no way |
382 | * to try a chdir or exec in the parent. Instead, all we need is a |
383 | * way to communicate any failure back to the parent. Easy; we just |
384 | * send the errno back to the parent over a pipe in case of failure. |
385 | * The tricky thing is, how do we communicate the *success* of exec? |
386 | * We use FD_CLOEXEC together with the fact that a read() on a pipe |
387 | * yields EOF when the write ends (we have two of them!) are closed. |
388 | */ |
389 | { |
390 | int errnum = errno; |
391 | restartableWrite(fail_pipe_fd, &errnum, sizeof(errnum)); |
392 | } |
393 | close(fail_pipe_fd); |
394 | _exit(-1); |
395 | return 0; /* Suppress warning "no return value from function" */ |
396 | } |
397 | |