1/* 2 * Copyright (c) 1995, 2015, 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#undef _LARGEFILE64_SOURCE 27#define _LARGEFILE64_SOURCE 1 28 29#include "jni.h" 30#include "jvm.h" 31#include "jvm_md.h" 32#include "jni_util.h" 33#include "io_util.h" 34 35/* 36 * Platform-specific support for java.lang.Process 37 */ 38#include <assert.h> 39#include <stddef.h> 40#include <stdlib.h> 41#include <sys/types.h> 42#include <ctype.h> 43#include <sys/wait.h> 44#include <signal.h> 45#include <string.h> 46 47#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX) 48#include <spawn.h> 49#endif 50 51#include "childproc.h" 52 53/* 54 * There are 4 possible strategies we might use to "fork": 55 * 56 * - fork(2). Very portable and reliable but subject to 57 * failure due to overcommit (see the documentation on 58 * /proc/sys/vm/overcommit_memory in Linux proc(5)). 59 * This is the ancient problem of spurious failure whenever a large 60 * process starts a small subprocess. 61 * 62 * - vfork(). Using this is scary because all relevant man pages 63 * contain dire warnings, e.g. Linux vfork(2). But at least it's 64 * documented in the glibc docs and is standardized by XPG4. 65 * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html 66 * On Linux, one might think that vfork() would be implemented using 67 * the clone system call with flag CLONE_VFORK, but in fact vfork is 68 * a separate system call (which is a good sign, suggesting that 69 * vfork will continue to be supported at least on Linux). 70 * Another good sign is that glibc implements posix_spawn using 71 * vfork whenever possible. Note that we cannot use posix_spawn 72 * ourselves because there's no reliable way to close all inherited 73 * file descriptors. 74 * 75 * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is 76 * Linux-specific, but this ought to work - at least the glibc 77 * sources contain code to handle different combinations of CLONE_VM 78 * and CLONE_THREAD. However, when this was implemented, it 79 * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with 80 * the simple program 81 * Runtime.getRuntime().exec("/bin/true").waitFor(); 82 * with: 83 * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536 84 * # Error: pthread_getattr_np failed with errno = 3 (ESRCH) 85 * We believe this is a glibc bug, reported here: 86 * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311 87 * but the glibc maintainers closed it as WONTFIX. 88 * 89 * - posix_spawn(). While posix_spawn() is a fairly elaborate and 90 * complicated system call, it can't quite do everything that the old 91 * fork()/exec() combination can do, so the only feasible way to do 92 * this, is to use posix_spawn to launch a new helper executable 93 * "jprochelper", which in turn execs the target (after cleaning 94 * up file-descriptors etc.) The end result is the same as before, 95 * a child process linked to the parent in the same way, but it 96 * avoids the problem of duplicating the parent (VM) process 97 * address space temporarily, before launching the target command. 98 * 99 * Based on the above analysis, we are currently using vfork() on 100 * Linux and posix_spawn() on other Unix systems. 101 */ 102 103 104static void 105setSIGCHLDHandler(JNIEnv *env) 106{ 107 /* There is a subtle difference between having the signal handler 108 * for SIGCHLD be SIG_DFL and SIG_IGN. We cannot obtain process 109 * termination information for child processes if the signal 110 * handler is SIG_IGN. It must be SIG_DFL. 111 * 112 * We used to set the SIGCHLD handler only on Linux, but it's 113 * safest to set it unconditionally. 114 * 115 * Consider what happens if java's parent process sets the SIGCHLD 116 * handler to SIG_IGN. Normally signal handlers are inherited by 117 * children, but SIGCHLD is a controversial case. Solaris appears 118 * to always reset it to SIG_DFL, but this behavior may be 119 * non-standard-compliant, and we shouldn't rely on it. 120 * 121 * References: 122 * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html 123 * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html 124 */ 125 struct sigaction sa; 126 sa.sa_handler = SIG_DFL; 127 sigemptyset(&sa.sa_mask); 128 sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; 129 if (sigaction(SIGCHLD, &sa, NULL) < 0) 130 JNU_ThrowInternalError(env, "Can't set SIGCHLD handler"); 131} 132 133static void* 134xmalloc(JNIEnv *env, size_t size) 135{ 136 void *p = malloc(size); 137 if (p == NULL) 138 JNU_ThrowOutOfMemoryError(env, NULL); 139 return p; 140} 141 142#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type))) 143 144/** 145 * If PATH is not defined, the OS provides some default value. 146 * Unfortunately, there's no portable way to get this value. 147 * Fortunately, it's only needed if the child has PATH while we do not. 148 */ 149static const char* 150defaultPath(void) 151{ 152#ifdef __solaris__ 153 /* These really are the Solaris defaults! */ 154 return (geteuid() == 0 || getuid() == 0) ? 155 "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : 156 "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:"; 157#else 158 return ":/bin:/usr/bin"; /* glibc */ 159#endif 160} 161 162static const char* 163effectivePath(void) 164{ 165 const char *s = getenv("PATH"); 166 return (s != NULL) ? s : defaultPath(); 167} 168 169static int 170countOccurrences(const char *s, char c) 171{ 172 int count; 173 for (count = 0; *s != '\0'; s++) 174 count += (*s == c); 175 return count; 176} 177 178static const char * const * 179effectivePathv(JNIEnv *env) 180{ 181 char *p; 182 int i; 183 const char *path = effectivePath(); 184 int count = countOccurrences(path, ':') + 1; 185 size_t pathvsize = sizeof(const char *) * (count+1); 186 size_t pathsize = strlen(path) + 1; 187 const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize); 188 189 if (pathv == NULL) 190 return NULL; 191 p = (char *) pathv + pathvsize; 192 memcpy(p, path, pathsize); 193 /* split PATH by replacing ':' with NULs; empty components => "." */ 194 for (i = 0; i < count; i++) { 195 char *q = p + strcspn(p, ":"); 196 pathv[i] = (p == q) ? "." : p; 197 *q = '\0'; 198 p = q + 1; 199 } 200 pathv[count] = NULL; 201 return pathv; 202} 203 204JNIEXPORT void JNICALL 205Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz) 206{ 207 parentPathv = effectivePathv(env); 208 CHECK_NULL(parentPathv); 209 setSIGCHLDHandler(env); 210} 211 212 213#ifndef WIFEXITED 214#define WIFEXITED(status) (((status)&0xFF) == 0) 215#endif 216 217#ifndef WEXITSTATUS 218#define WEXITSTATUS(status) (((status)>>8)&0xFF) 219#endif 220 221#ifndef WIFSIGNALED 222#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0) 223#endif 224 225#ifndef WTERMSIG 226#define WTERMSIG(status) ((status)&0x7F) 227#endif 228 229static const char * 230getBytes(JNIEnv *env, jbyteArray arr) 231{ 232 return arr == NULL ? NULL : 233 (const char*) (*env)->GetByteArrayElements(env, arr, NULL); 234} 235 236static void 237releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr) 238{ 239 if (parr != NULL) 240 (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT); 241} 242 243#define IOE_FORMAT "error=%d, %s" 244 245static void 246throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) 247{ 248 const char *detail = defaultDetail; 249 char *errmsg; 250 size_t fmtsize; 251 char tmpbuf[1024]; 252 jstring s; 253 254 if (errnum != 0) { 255 int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf)); 256 if (ret != EINVAL) 257 detail = tmpbuf; 258 } 259 /* ASCII Decimal representation uses 2.4 times as many bits as binary. */ 260 fmtsize = sizeof(IOE_FORMAT) + strlen(detail) + 3 * sizeof(errnum); 261 errmsg = NEW(char, fmtsize); 262 if (errmsg == NULL) 263 return; 264 265 snprintf(errmsg, fmtsize, IOE_FORMAT, errnum, detail); 266 s = JNU_NewStringPlatform(env, errmsg); 267 if (s != NULL) { 268 jobject x = JNU_NewObjectByName(env, "java/io/IOException", 269 "(Ljava/lang/String;)V", s); 270 if (x != NULL) 271 (*env)->Throw(env, x); 272 } 273 free(errmsg); 274} 275 276#ifdef DEBUG_PROCESS 277/* Debugging process code is difficult; where to write debug output? */ 278static void 279debugPrint(char *format, ...) 280{ 281 FILE *tty = fopen("/dev/tty", "w"); 282 va_list ap; 283 va_start(ap, format); 284 vfprintf(tty, format, ap); 285 va_end(ap); 286 fclose(tty); 287} 288#endif /* DEBUG_PROCESS */ 289 290static void 291copyPipe(int from[2], int to[2]) 292{ 293 to[0] = from[0]; 294 to[1] = from[1]; 295} 296 297/* arg is an array of pointers to 0 terminated strings. array is terminated 298 * by a null element. 299 * 300 * *nelems and *nbytes receive the number of elements of array (incl 0) 301 * and total number of bytes (incl. 0) 302 * Note. An empty array will have one null element 303 * But if arg is null, then *nelems set to 0, and *nbytes to 0 304 */ 305static void arraysize(const char * const *arg, int *nelems, int *nbytes) 306{ 307 int i, bytes, count; 308 const char * const *a = arg; 309 char *p; 310 int *q; 311 if (arg == 0) { 312 *nelems = 0; 313 *nbytes = 0; 314 return; 315 } 316 /* count the array elements and number of bytes */ 317 for (count=0, bytes=0; *a != 0; count++, a++) { 318 bytes += strlen(*a)+1; 319 } 320 *nbytes = bytes; 321 *nelems = count+1; 322} 323 324/* copy the strings from arg[] into buf, starting at given offset 325 * return new offset to next free byte 326 */ 327static int copystrings(char *buf, int offset, const char * const *arg) { 328 char *p; 329 const char * const *a; 330 int count=0; 331 332 if (arg == 0) { 333 return offset; 334 } 335 for (p=buf+offset, a=arg; *a != 0; a++) { 336 int len = strlen(*a) +1; 337 memcpy(p, *a, len); 338 p += len; 339 count += len; 340 } 341 return offset+count; 342} 343 344/** 345 * We are unusually paranoid; use of vfork is 346 * especially likely to tickle gcc/glibc bugs. 347 */ 348#ifdef __attribute_noinline__ /* See: sys/cdefs.h */ 349__attribute_noinline__ 350#endif 351 352/* vfork(2) is deprecated on Solaris */ 353#ifndef __solaris__ 354static pid_t 355vforkChild(ChildStuff *c) { 356 volatile pid_t resultPid; 357 358 /* 359 * We separate the call to vfork into a separate function to make 360 * very sure to keep stack of child from corrupting stack of parent, 361 * as suggested by the scary gcc warning: 362 * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork' 363 */ 364 resultPid = vfork(); 365 366 if (resultPid == 0) { 367 childProcess(c); 368 } 369 assert(resultPid != 0); /* childProcess never returns */ 370 return resultPid; 371} 372#endif 373 374static pid_t 375forkChild(ChildStuff *c) { 376 pid_t resultPid; 377 378 /* 379 * From Solaris fork(2): In Solaris 10, a call to fork() is 380 * identical to a call to fork1(); only the calling thread is 381 * replicated in the child process. This is the POSIX-specified 382 * behavior for fork(). 383 */ 384 resultPid = fork(); 385 386 if (resultPid == 0) { 387 childProcess(c); 388 } 389 assert(resultPid != 0); /* childProcess never returns */ 390 return resultPid; 391} 392 393#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX) 394static pid_t 395spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) { 396 pid_t resultPid; 397 jboolean isCopy; 398 int i, offset, rval, bufsize, magic; 399 char *buf, buf1[16]; 400 char *hlpargs[2]; 401 SpawnInfo sp; 402 403 /* need to tell helper which fd is for receiving the childstuff 404 * and which fd to send response back on 405 */ 406 snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]); 407 /* put the fd string as argument to the helper cmd */ 408 hlpargs[0] = buf1; 409 hlpargs[1] = 0; 410 411 /* Following items are sent down the pipe to the helper 412 * after it is spawned. 413 * All strings are null terminated. All arrays of strings 414 * have an empty string for termination. 415 * - the ChildStuff struct 416 * - the SpawnInfo struct 417 * - the argv strings array 418 * - the envv strings array 419 * - the home directory string 420 * - the parentPath string 421 * - the parentPathv array 422 */ 423 /* First calculate the sizes */ 424 arraysize(c->argv, &sp.nargv, &sp.argvBytes); 425 bufsize = sp.argvBytes; 426 arraysize(c->envv, &sp.nenvv, &sp.envvBytes); 427 bufsize += sp.envvBytes; 428 sp.dirlen = c->pdir == 0 ? 0 : strlen(c->pdir)+1; 429 bufsize += sp.dirlen; 430 arraysize(parentPathv, &sp.nparentPathv, &sp.parentPathvBytes); 431 bufsize += sp.parentPathvBytes; 432 /* We need to clear FD_CLOEXEC if set in the fds[]. 433 * Files are created FD_CLOEXEC in Java. 434 * Otherwise, they will be closed when the target gets exec'd */ 435 for (i=0; i<3; i++) { 436 if (c->fds[i] != -1) { 437 int flags = fcntl(c->fds[i], F_GETFD); 438 if (flags & FD_CLOEXEC) { 439 fcntl(c->fds[i], F_SETFD, flags & (~1)); 440 } 441 } 442 } 443 444 rval = posix_spawn(&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ); 445 446 if (rval != 0) { 447 return -1; 448 } 449 450 /* now the lengths are known, copy the data */ 451 buf = NEW(char, bufsize); 452 if (buf == 0) { 453 return -1; 454 } 455 offset = copystrings(buf, 0, &c->argv[0]); 456 offset = copystrings(buf, offset, &c->envv[0]); 457 memcpy(buf+offset, c->pdir, sp.dirlen); 458 offset += sp.dirlen; 459 offset = copystrings(buf, offset, parentPathv); 460 assert(offset == bufsize); 461 462 magic = magicNumber(); 463 464 /* write the two structs and the data buffer */ 465 write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first 466 write(c->childenv[1], (char *)c, sizeof(*c)); 467 write(c->childenv[1], (char *)&sp, sizeof(sp)); 468 write(c->childenv[1], buf, bufsize); 469 free(buf); 470 471 /* In this mode an external main() in invoked which calls back into 472 * childProcess() in this file, rather than directly 473 * via the statement below */ 474 return resultPid; 475} 476#endif 477 478/* 479 * Start a child process running function childProcess. 480 * This function only returns in the parent. 481 */ 482static pid_t 483startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) { 484 switch (c->mode) { 485/* vfork(2) is deprecated on Solaris */ 486#ifndef __solaris__ 487 case MODE_VFORK: 488 return vforkChild(c); 489#endif 490 case MODE_FORK: 491 return forkChild(c); 492#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX) 493 case MODE_POSIX_SPAWN: 494 return spawnChild(env, process, c, helperpath); 495#endif 496 default: 497 return -1; 498 } 499} 500 501JNIEXPORT jint JNICALL 502Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env, 503 jobject process, 504 jint mode, 505 jbyteArray helperpath, 506 jbyteArray prog, 507 jbyteArray argBlock, jint argc, 508 jbyteArray envBlock, jint envc, 509 jbyteArray dir, 510 jintArray std_fds, 511 jboolean redirectErrorStream) 512{ 513 int errnum; 514 int resultPid = -1; 515 int in[2], out[2], err[2], fail[2], childenv[2]; 516 jint *fds = NULL; 517 const char *phelperpath = NULL; 518 const char *pprog = NULL; 519 const char *pargBlock = NULL; 520 const char *penvBlock = NULL; 521 ChildStuff *c; 522 523 in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1; 524 childenv[0] = childenv[1] = -1; 525 526 if ((c = NEW(ChildStuff, 1)) == NULL) return -1; 527 c->argv = NULL; 528 c->envv = NULL; 529 c->pdir = NULL; 530 531 /* Convert prog + argBlock into a char ** argv. 532 * Add one word room for expansion of argv for use by 533 * execve_as_traditional_shell_script. 534 * This word is also used when using posix_spawn mode 535 */ 536 assert(prog != NULL && argBlock != NULL); 537 if ((phelperpath = getBytes(env, helperpath)) == NULL) goto Catch; 538 if ((pprog = getBytes(env, prog)) == NULL) goto Catch; 539 if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch; 540 if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch; 541 c->argv[0] = pprog; 542 c->argc = argc + 2; 543 initVectorFromBlock(c->argv+1, pargBlock, argc); 544 545 if (envBlock != NULL) { 546 /* Convert envBlock into a char ** envv */ 547 if ((penvBlock = getBytes(env, envBlock)) == NULL) goto Catch; 548 if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch; 549 initVectorFromBlock(c->envv, penvBlock, envc); 550 } 551 552 if (dir != NULL) { 553 if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch; 554 } 555 556 assert(std_fds != NULL); 557 fds = (*env)->GetIntArrayElements(env, std_fds, NULL); 558 if (fds == NULL) goto Catch; 559 560 if ((fds[0] == -1 && pipe(in) < 0) || 561 (fds[1] == -1 && pipe(out) < 0) || 562 (fds[2] == -1 && pipe(err) < 0) || 563 (pipe(childenv) < 0) || 564 (pipe(fail) < 0)) { 565 throwIOException(env, errno, "Bad file descriptor"); 566 goto Catch; 567 } 568 c->fds[0] = fds[0]; 569 c->fds[1] = fds[1]; 570 c->fds[2] = fds[2]; 571 572 copyPipe(in, c->in); 573 copyPipe(out, c->out); 574 copyPipe(err, c->err); 575 copyPipe(fail, c->fail); 576 copyPipe(childenv, c->childenv); 577 578 c->redirectErrorStream = redirectErrorStream; 579 c->mode = mode; 580 581 resultPid = startChild(env, process, c, phelperpath); 582 assert(resultPid != 0); 583 584 if (resultPid < 0) { 585 switch (c->mode) { 586 case MODE_VFORK: 587 throwIOException(env, errno, "vfork failed"); 588 break; 589 case MODE_FORK: 590 throwIOException(env, errno, "fork failed"); 591 break; 592 case MODE_POSIX_SPAWN: 593 throwIOException(env, errno, "posix_spawn failed"); 594 break; 595 } 596 goto Catch; 597 } 598 close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec (childproc.c) */ 599 600 switch (readFully(fail[0], &errnum, sizeof(errnum))) { 601 case 0: break; /* Exec succeeded */ 602 case sizeof(errnum): 603 waitpid(resultPid, NULL, 0); 604 throwIOException(env, errnum, "Exec failed"); 605 goto Catch; 606 default: 607 throwIOException(env, errno, "Read failed"); 608 goto Catch; 609 } 610 611 fds[0] = (in [1] != -1) ? in [1] : -1; 612 fds[1] = (out[0] != -1) ? out[0] : -1; 613 fds[2] = (err[0] != -1) ? err[0] : -1; 614 615 Finally: 616 /* Always clean up the child's side of the pipes */ 617 closeSafely(in [0]); 618 closeSafely(out[1]); 619 closeSafely(err[1]); 620 621 /* Always clean up fail and childEnv descriptors */ 622 closeSafely(fail[0]); 623 closeSafely(fail[1]); 624 closeSafely(childenv[0]); 625 closeSafely(childenv[1]); 626 627 releaseBytes(env, helperpath, phelperpath); 628 releaseBytes(env, prog, pprog); 629 releaseBytes(env, argBlock, pargBlock); 630 releaseBytes(env, envBlock, penvBlock); 631 releaseBytes(env, dir, c->pdir); 632 633 free(c->argv); 634 free(c->envv); 635 free(c); 636 637 if (fds != NULL) 638 (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0); 639 640 return resultPid; 641 642 Catch: 643 /* Clean up the parent's side of the pipes in case of failure only */ 644 closeSafely(in [1]); in[1] = -1; 645 closeSafely(out[0]); out[0] = -1; 646 closeSafely(err[0]); err[0] = -1; 647 goto Finally; 648} 649 650