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 }