1 #include <dirent.h> 2 #include <errno.h> 3 #include <fcntl.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <limits.h> 8 9 #include "childproc.h" 10 11 12 #ifndef STDIN_FILENO 13 #define STDIN_FILENO 0 14 #endif 15 16 #ifndef STDOUT_FILENO 17 #define STDOUT_FILENO 1 18 #endif 19 20 #ifndef STDERR_FILENO 21 #define STDERR_FILENO 2 22 #endif 23 24 #define FAIL_FILENO (STDERR_FILENO + 1) 25 26 /** 27 * Cached value of JVM's effective PATH. 28 * (We don't support putenv("PATH=...") in native code) 29 */ 30 const char *parentPath; 31 /** 32 * Split, canonicalized version of parentPath 33 */ 34 const char * const *parentPathv; 35 36 /* TODO: Refactor. */ 37 #define RESTARTABLE(_cmd, _result) do { \ 38 do { \ 39 _result = _cmd; \ 40 } while((_result == -1) && (errno == EINTR)); \ 41 } while(0) 42 43 ssize_t restartableWrite(int fd, const void *buf, size_t count) 44 { 45 ssize_t result; 46 RESTARTABLE(write(fd, buf, count), result); 47 return result; 48 } 49 50 int restartableDup2(int fd_from, int fd_to) 51 { 52 int err; 53 RESTARTABLE(dup2(fd_from, fd_to), err); 54 return err; 55 } 56 57 int restartableClose(int fd) 58 { 59 int err; 60 RESTARTABLE(close(fd), err); 61 return err; 62 } 63 64 int closeSafely(int fd) 65 { 66 return (fd == -1) ? 0 : restartableClose(fd); 67 } 68 69 #ifdef _ALLBSD_SOURCE 70 #define FD_DIR "/dev/fd" 71 #define dirent64 dirent 72 #define readdir64 readdir 73 #else 74 #define FD_DIR "/proc/self/fd" 75 #endif 76 77 int isAsciiDigit(char c) 78 { 79 return c >= '0' && c <= '9'; 80 } 81 82 int closeDescriptors(void) 83 { 84 DIR *dp; 85 struct dirent64 *dirp; 86 int from_fd = FAIL_FILENO + 1; 87 88 /* We're trying to close all file descriptors, but opendir() might 89 * itself be implemented using a file descriptor, and we certainly 90 * don't want to close that while it's in use. We assume that if 91 * opendir() is implemented using a file descriptor, then it uses 92 * the lowest numbered file descriptor, just like open(). So we 93 * close a couple explicitly. */ 94 95 restartableClose(from_fd); /* for possible use by opendir() */ 96 restartableClose(from_fd + 1); /* another one for good luck */ 97 98 if ((dp = opendir(FD_DIR)) == NULL) 99 return 0; 100 101 /* We use readdir64 instead of readdir to work around Solaris bug 102 * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9 103 */ 104 while ((dirp = readdir64(dp)) != NULL) { 105 int fd; 106 if (isAsciiDigit(dirp->d_name[0]) && 107 (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2) 108 restartableClose(fd); 109 } 110 111 closedir(dp); 112 113 return 1; 114 } 115 116 int moveDescriptor(int fd_from, int fd_to) 117 { 118 if (fd_from != fd_to) { 119 if ((restartableDup2(fd_from, fd_to) == -1) || 120 (restartableClose(fd_from) == -1)) { 121 return -1; 122 } 123 } 124 return 0; 125 } 126 127 int 128 magicNumber() { 129 return 43110; 130 } 131 132 /* 133 * Reads nbyte bytes from file descriptor fd into buf. 134 * The read operation is retried in case of EINTR or partial reads. 135 * 136 * Returns number of bytes read (normally nbyte, but may be less in 137 * case of EOF). In case of read errors, returns -1 and sets errno. 138 */ 139 ssize_t 140 readFully(int fd, void *buf, size_t nbyte) 141 { 142 ssize_t remaining = nbyte; 143 for (;;) { 144 ssize_t n = read(fd, buf, remaining); 145 if (n == 0) { 146 return nbyte - remaining; 147 } else if (n > 0) { 148 remaining -= n; 149 if (remaining <= 0) 150 return nbyte; 151 /* We were interrupted in the middle of reading the bytes. 152 * Unlikely, but possible. */ 153 buf = (void *) (((char *)buf) + n); 154 } else if (errno == EINTR) { 155 /* Strange signals like SIGJVM1 are possible at any time. 156 * See http://www.dreamsongs.com/WorseIsBetter.html */ 157 } else { 158 return -1; 159 } 160 } 161 } 162 163 void 164 initVectorFromBlock(const char**vector, const char* block, int count) 165 { 166 int i; 167 const char *p; 168 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 173 while (*(p++)); 174 } 175 vector[count] = NULL; 176 } 177 178 /** 179 * Exec FILE as a traditional Bourne shell script (i.e. one without #!). 180 * If we could do it over again, we would probably not support such an ancient 181 * misfeature, but compatibility wins over sanity. The original support for 182 * this was imported accidentally from execvp(). 183 */ 184 void 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 execve_with_shell_fallback(int mode, const char *file, 207 const char *argv[], 208 const char *const envp[]) 209 { 210 if (mode == MODE_CLONE || mode == MODE_VFORK) { 211 /* shared address space; be very careful. */ 212 execve(file, (char **) argv, (char **) envp); 213 if (errno == ENOEXEC) 214 execve_as_traditional_shell_script(file, argv, envp); 215 } else { 216 /* unshared address space; we can mutate environ. */ 217 environ = (char **) envp; 218 execvp(file, (char **) argv); 219 } 220 } 221 222 /** 223 * 'execvpe' should have been included in the Unix standards, 224 * and is a GNU extension in glibc 2.10. 225 * 226 * JDK_execvpe is identical to execvp, except that the child environment is 227 * specified via the 3rd argument instead of being inherited from environ. 228 */ 229 void JDK_execvpe(int mode, const char *file, 230 const char *argv[], 231 const char *const envp[]) 232 { 233 if (envp == NULL || (char **) envp == environ) { 234 execvp(file, (char **) argv); 235 return; 236 } 237 238 if (*file == '\0') { 239 errno = ENOENT; 240 return; 241 } 242 243 if (strchr(file, '/') != NULL) { 244 execve_with_shell_fallback(mode, file, argv, envp); 245 } else { 246 /* We must search PATH (parent's, not child's) */ 247 char expanded_file[PATH_MAX]; 248 int filelen = strlen(file); 249 int sticky_errno = 0; 250 const char * const * dirs; 251 252 for (dirs = parentPathv; *dirs; dirs++) { 253 const char * dir = *dirs; 254 int dirlen = strlen(dir); 255 if (filelen + dirlen + 1 >= PATH_MAX) { 256 errno = ENAMETOOLONG; 257 continue; 258 } 259 memcpy(expanded_file, dir, dirlen); 260 memcpy(expanded_file + dirlen, file, filelen); 261 expanded_file[dirlen + filelen] = '\0'; 262 execve_with_shell_fallback(mode, expanded_file, argv, envp); 263 /* There are 3 responses to various classes of errno: 264 * return immediately, continue (especially for ENOENT), 265 * or continue with "sticky" errno. 266 * 267 * From exec(3): 268 * 269 * If permission is denied for a file (the attempted 270 * execve returned EACCES), these functions will continue 271 * searching the rest of the search path. If no other 272 * file is found, however, they will return with the 273 * global variable errno set to EACCES. 274 */ 275 switch (errno) { 276 case EACCES: 277 sticky_errno = errno; 278 /* FALLTHRU */ 279 case ENOENT: 280 case ENOTDIR: 281 #ifdef ELOOP 282 case ELOOP: 283 #endif 284 #ifdef ESTALE 285 case ESTALE: 286 #endif 287 #ifdef ENODEV 288 case ENODEV: 289 #endif 290 #ifdef ETIMEDOUT 291 case ETIMEDOUT: 292 #endif 293 break; /* Try other directories in PATH */ 294 default: 295 return; 296 } 297 } 298 if (sticky_errno != 0) 299 errno = sticky_errno; 300 } 301 } 302 303 int 304 childProcess(void *arg) 305 { 306 ChildStuff* p = (ChildStuff*) arg; 307 308 /* Close the parent sides of the pipes. 309 Closing pipe fds here is redundant, since closeDescriptors() 310 would do it anyways, but a little paranoia is a good thing. 311 We close both sides of the childenv pipe since in spawn 312 mode we are finished with it now, and it's not used at all 313 in the other modes */ 314 if ((closeSafely(p->in[1]) == -1) || 315 (closeSafely(p->out[0]) == -1) || 316 (closeSafely(p->err[0]) == -1) || 317 (closeSafely(p->childenv[0]) == -1) || 318 (closeSafely(p->childenv[1]) == -1) || 319 (closeSafely(p->fail[0]) == -1)) 320 goto WhyJohnnyCantExec; 321 322 p->in[1] = -1; p->out[0] = -1; p->err[0] = -1; 323 p->childenv[0] = -1; p->childenv[1] = -1; p->fail[0] = -1; 324 325 /* Give the child sides of the pipes the right fileno's. */ 326 /* Note: it is possible for in[0] == 0 */ 327 if ((moveDescriptor(p->in[0] != -1 ? p->in[0] : p->fds[0], 328 STDIN_FILENO) == -1) || 329 (moveDescriptor(p->out[1]!= -1 ? p->out[1] : p->fds[1], 330 STDOUT_FILENO) == -1)) { 331 goto WhyJohnnyCantExec; 332 } 333 334 if (p->redirectErrorStream) { 335 if ((closeSafely(p->err[1]) == -1) || 336 (restartableDup2(STDOUT_FILENO, STDERR_FILENO) == -1)) 337 goto WhyJohnnyCantExec; 338 } else { 339 if (moveDescriptor(p->err[1] != -1 ? p->err[1] : p->fds[2], 340 STDERR_FILENO) == -1) 341 goto WhyJohnnyCantExec; 342 } 343 344 if (moveDescriptor(p->fail[1], FAIL_FILENO) == -1) 345 goto WhyJohnnyCantExec; 346 347 /* close everything */ 348 if (closeDescriptors() == 0) { /* failed, close the old way */ 349 int max_fd = (int)sysconf(_SC_OPEN_MAX); 350 int fd; 351 for (fd = FAIL_FILENO + 1; fd < max_fd; fd++) 352 if (restartableClose(fd) == -1 && errno != EBADF) 353 goto WhyJohnnyCantExec; 354 } 355 356 /* change to the new working directory */ 357 if (p->pdir != NULL && chdir(p->pdir) < 0) 358 goto WhyJohnnyCantExec; 359 360 if (fcntl(FAIL_FILENO, F_SETFD, FD_CLOEXEC) == -1) 361 goto WhyJohnnyCantExec; 362 363 JDK_execvpe(p->mode, p->argv[0], p->argv, p->envv); 364 365 WhyJohnnyCantExec: 366 /* We used to go to an awful lot of trouble to predict whether the 367 * child would fail, but there is no reliable way to predict the 368 * success of an operation without *trying* it, and there's no way 369 * to try a chdir or exec in the parent. Instead, all we need is a 370 * way to communicate any failure back to the parent. Easy; we just 371 * send the errno back to the parent over a pipe in case of failure. 372 * The tricky thing is, how do we communicate the *success* of exec? 373 * We use FD_CLOEXEC together with the fact that a read() on a pipe 374 * yields EOF when the write ends (we have two of them!) are closed. 375 */ 376 { 377 int errnum = errno; 378 restartableWrite(FAIL_FILENO, &errnum, sizeof(errnum)); 379 } 380 restartableClose(FAIL_FILENO); 381 _exit(-1); 382 return 0; /* Suppress warning "no return value from function" */ 383 }