Print this page
    
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/exec/java/java.c
          +++ new/usr/src/uts/common/exec/java/java.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + * Copyright 2015, Joyent, Inc.
  24   25   */
  25   26  
  26   27  /*
  27   28   * Launch Java executables via exec(2).
  28   29   *
  29   30   * Java executables are platform-independent executable files
  30   31   * based on the JAR file format.  Executable JAR files contain a
  31   32   * special 'extra field' header in the first file of the archive
  32   33   * that marks the file as a true executable.   The data in that field
  33   34   * is used to pass additional run-time information to the Java VM.
  34   35   *
  35   36   * This handler looks for the appropriate magic number on the
  36   37   * front of the file, checks that the JAR file is executable, then
  37   38   * invokes the Java runtime environment to do the rest of the work.
  38   39   */
  39   40  
  40   41  #include <sys/types.h>
  41   42  #include <sys/proc.h>
  42   43  #include <sys/vnode.h>
  43   44  #include <sys/exec.h>
  44   45  #include <sys/modctl.h>
  45   46  #include <sys/cmn_err.h>
  46   47  #include <sys/pathname.h>
  47   48  
  48   49  /*
  49   50   * These variables can be tweaked via /etc/system to allow prototyping
  50   51   * and debugging.  See PSARC/1997/123.
  51   52   *
  52   53   * Modified by PSARC/1999/012 to be Contract Private between Solaris and
  53   54   * the Java Technology Group.  It is expected that any future change to
  54   55   * these variables be coordinated between the consolidations.
  55   56   */
  56   57  #if defined(__sparc)
  57   58  char *jexec = "/usr/java/jre/lib/sparc/jexec";
  58   59  #elif defined(__i386) || defined(__i386_COMPAT)
  59   60  char *jexec = "/usr/java/jre/lib/i386/jexec";
  60   61  #else
  61   62  #error "Unknown ISA"
  62   63  #endif
  63   64  char *jexec_arg = "-jar";
  64   65  
  65   66  /*
  66   67   * ZIP/JAR file header information
  67   68   */
  68   69  #define SIGSIZ          4
  69   70  #define LOCSIG          "PK\003\004"
  70   71  #define LOCHDRSIZ       30
  71   72  
  72   73  #define CH(b, n)        (((unsigned char *)(b))[n])
  73   74  #define SH(b, n)        (CH(b, n) | (CH(b, n+1) << 8))
  74   75  #define LG(b, n)        (SH(b, n) | (SH(b, n+2) << 16))
  75   76  
  76   77  #define LOCNAM(b)       (SH(b, 26))     /* filename size */
  77   78  #define LOCEXT(b)       (SH(b, 28))     /* extra field size */
  
    | 
      ↓ open down ↓ | 
    44 lines elided | 
    
      ↑ open up ↑ | 
  
  78   79  
  79   80  #define XFHSIZ          4               /* header id, data size */
  80   81  #define XFHID(b)        (SH(b, 0))      /* extract field header id */
  81   82  #define XFDATASIZ(b)    (SH(b, 2))      /* extract field data size */
  82   83  #define XFJAVASIG       0xcafe          /* java executables */
  83   84  
  84   85  /*ARGSUSED3*/
  85   86  static int
  86   87  javaexec(vnode_t *vp, struct execa *uap, struct uarg *args,
  87   88      struct intpdata *idatap, int level, long *execsz, int setid,
  88      -    caddr_t execfile, cred_t *cred, int brand_action)
       89 +    caddr_t execfile, cred_t *cred, int *brand_action)
  89   90  {
  90   91          struct intpdata idata;
  91   92          int error;
  92   93          ssize_t resid;
  93   94          vnode_t *nvp;
  94   95          off_t xoff, xoff_end;
  95   96          char lochdr[LOCHDRSIZ];
  96   97          struct pathname lookpn;
  97   98          struct pathname resolvepn;
  98   99          char *opath;
  99  100  
 100  101          if (level)
 101  102                  return (ENOEXEC);       /* no recursion */
 102  103  
 103  104          /*
 104  105           * Read in the full local file header, and validate
 105  106           * the initial signature.
 106  107           */
 107  108          if ((error = vn_rdwr(UIO_READ, vp, lochdr, sizeof (lochdr),
 108  109              0, UIO_SYSSPACE, 0, (rlim64_t)0, cred, &resid)) != 0)
 109  110                  return (error);
 110  111          if (resid != 0 || strncmp(lochdr, LOCSIG, SIGSIZ) != 0)
 111  112                  return (ENOEXEC);
 112  113  
 113  114          /*
 114  115           * Ok, so this -is- a ZIP file, and might even be a JAR file.
 115  116           * Is it a Java executable?
 116  117           */
 117  118          xoff = sizeof (lochdr) + LOCNAM(lochdr);
 118  119          xoff_end = xoff + LOCEXT(lochdr);
 119  120  
 120  121          while (xoff < xoff_end) {
 121  122                  char xfhdr[XFHSIZ];
 122  123  
 123  124                  if ((error = vn_rdwr(UIO_READ, vp, xfhdr, sizeof (xfhdr),
 124  125                      xoff, UIO_SYSSPACE, 0, (rlim64_t)0, cred, &resid)) != 0)
 125  126                          return (error);
 126  127                  if (resid != 0)
 127  128                          return (ENOEXEC);
 128  129                  if (XFHID(xfhdr) == XFJAVASIG)
 129  130                          break;
 130  131                  xoff += sizeof (xfhdr) + XFDATASIZ(xfhdr);
 131  132          }
 132  133  
 133  134          if (xoff >= xoff_end)
 134  135                  return (ENOEXEC);
 135  136  
 136  137          /*
 137  138           * Note: If we ever make setid execution work, we need to ensure
 138  139           * that we use /dev/fd to avoid the classic setuid shell script
 139  140           * security hole.
 140  141           */
 141  142          if (setid)
 142  143                  return (EACCES);
 143  144  
 144  145          /*
 145  146           * Find and invoke the Java runtime environment on the file
 146  147           */
 147  148          idata.intp = NULL;
 148  149          idata.intp_name[0] = jexec;
 149  150          idata.intp_arg[0] = jexec_arg;
 150  151          if (error = pn_get(idata.intp_name[0], UIO_SYSSPACE, &lookpn))
 151  152                  return (error);
 152  153          pn_alloc(&resolvepn);
 153  154          if (error = lookuppn(&lookpn, &resolvepn, FOLLOW, NULLVPP, &nvp)) {
 154  155                  pn_free(&resolvepn);
 155  156                  pn_free(&lookpn);
 156  157                  return (ENOEXEC);
 157  158          }
 158  159          opath = args->pathname;
 159  160          args->pathname = resolvepn.pn_path;
 160  161          /* don't free resolvepn until we are done with args */
 161  162          pn_free(&lookpn);
 162  163          error = gexec(&nvp, uap, args, &idata, level + 1, execsz, execfile,
 163  164              cred, EBA_NONE);
 164  165  
 165  166          if (!error) {
 166  167                  /*
 167  168                   * Close this Java executable as the interpreter
 168  169                   * will open and close it later on.
 169  170                   */
 170  171                  (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL);
 171  172          }
 172  173  
 173  174          VN_RELE(nvp);
 174  175          args->pathname = opath;
 175  176          pn_free(&resolvepn);
 176  177          return (error);
 177  178  }
 178  179  
 179  180  static struct execsw jexecsw = {
 180  181          javamagicstr,
 181  182          0,
 182  183          4,
 183  184          javaexec,
 184  185          NULL
 185  186  };
 186  187  
 187  188  static struct modlexec jmodlexec = {
 188  189          &mod_execops, "exec for Java", &jexecsw
 189  190  };
 190  191  
 191  192  static struct modlinkage jmodlinkage = {
 192  193          MODREV_1, &jmodlexec, NULL
 193  194  };
 194  195  
 195  196  int
 196  197  _init(void)
 197  198  {
 198  199          return (mod_install(&jmodlinkage));
 199  200  }
 200  201  
 201  202  int
 202  203  _fini(void)
 203  204  {
 204  205          return (mod_remove(&jmodlinkage));
 205  206  }
 206  207  
 207  208  int
 208  209  _info(struct modinfo *modinfop)
 209  210  {
 210  211          return (mod_info(&jmodlinkage, modinfop));
 211  212  }
  
    | 
      ↓ open down ↓ | 
    113 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX