Print this page
OS-5354 lx shebang argument handling is incorrect
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4364 intpexec mishandles process branding
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
@@ -20,10 +20,11 @@
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2016, Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
@@ -45,18 +46,19 @@
#include <sys/disp.h>
#include <sys/exec.h>
#include <sys/kmem.h>
#include <sys/note.h>
#include <sys/sdt.h>
+#include <sys/brand.h>
/*
* This is the loadable module wrapper.
*/
#include <sys/modctl.h>
extern int intpexec(struct vnode *, struct execa *, struct uarg *,
- struct intpdata *, int, long *, int, caddr_t, struct cred *, int);
+ struct intpdata *, int, long *, int, caddr_t, struct cred *, int *);
static struct execsw esw = {
intpmagicstr,
0,
2,
@@ -124,17 +126,24 @@
return (ENOEXEC);
ASSERT(*cp == '\n');
*cp = '\0';
/*
- * Locate the beginning and end of the interpreter name.
- * In addition to the name, one additional argument may
- * optionally be included here, to be prepended to the
- * arguments provided on the command line. Thus, for
- * example, you can say
+ * Locate the beginning and end of the interpreter name. Historically,
+ * for illumos and its predecessors, in addition to the name, one
+ * additional argument may optionally be included here, to be prepended
+ * to the arguments provided on the command line. Thus, for example,
+ * you can say
*
* #! /usr/bin/awk -f
+ *
+ * However, handling of interpreter arguments varies across operating
+ * systems and other systems allow more than one argument. In
+ * particular, Linux allows more than one and delivers all arguments
+ * as a single string (argv[1] is "-arg1 -arg2 ..."). We support this
+ * style of argument handling as a brand-specific option (setting
+ * b_intp_parse_arg to B_FALSE).
*/
for (cp = &linep[2]; *cp == ' '; cp++)
;
if (*cp == '\0')
return (ENOEXEC);
@@ -149,15 +158,18 @@
cp++;
if (*cp == '\0')
idatap->intp_arg[0] = NULL;
else {
idatap->intp_arg[0] = cp;
+ if (!PROC_IS_BRANDED(curproc) ||
+ BROP(curproc)->b_intp_parse_arg) {
while (*cp && *cp != ' ')
cp++;
*cp = '\0';
}
}
+ }
return (0);
}
/*
* We support nested interpreters up to a depth of INTP_MAXDEPTH (this value
@@ -186,13 +198,12 @@
int level,
long *execsz,
int setid,
caddr_t exec_file,
struct cred *cred,
- int brand_action)
+ int *brand_action)
{
- _NOTE(ARGUNUSED(brand_action))
vnode_t *nvp;
int error = 0;
struct intpdata idata;
struct pathname intppn;
struct pathname resolvepn;
@@ -279,11 +290,11 @@
numtos(fd, &devfd[8]);
args->fname = devfd;
}
error = gexec(&nvp, uap, args, &idata, ++level, execsz, exec_file, cred,
- EBA_NONE);
+ brand_action);
if (!error) {
/*
* Close this executable as the interpreter
* will open and close it later on.