Print this page
Reduce lint
OS-4818 contract template disappears on exec
OS-4460 exec brands processes that still have multiple threads
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-3742 lxbrand add support for signalfd
OS-4382 remove obsolete brand hooks added during lx development
OS-4188 NULL dereference in lwp_hash_in
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4151 setbrand hooks should be sane during fork
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4129 lxbrand should not abuse p_brand_data for storing exit signal
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-3561 lxbrand emulation library should execute on alternate stack
OS-3558 lxbrand add support for full in-kernel syscall handling
OS-3545 lx_syscall_regs should not walk stack
OS-3868 many LTP testcases now hang
OS-3901 lxbrand lx_recvmsg fails to translate control messages when 64-bit
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
OS-3871 AT_RANDOM aux entry should be populated using random_get_pseudo_bytes
OS-3611 lx brand: 64-bit processes should not use VAs above VA hole
OS-3438 lx brand: "start rsyslog" hangs
OS-3280 need a way to specify the root of a native system in the lx brand
OS-3279 lx brand should allow delegated datasets
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-2949 add support for AT_RANDOM aux vector entry
*** 24,34 ****
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
! * Copyright 2014, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
--- 24,34 ----
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
! * Copyright 2015, Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
*** 67,76 ****
--- 67,77 ----
#include <sys/lwpchan_impl.h>
#include <sys/pool.h>
#include <sys/sdt.h>
#include <sys/brand.h>
#include <sys/klpd.h>
+ #include <sys/random.h>
#include <c2/audit.h>
#include <vm/hat.h>
#include <vm/anon.h>
*** 95,104 ****
--- 96,106 ----
uint_t auxv_hwcap32 = 0; /* 32-bit version of auxv_hwcap */
uint_t auxv_hwcap32_2 = 0; /* 32-bit version of auxv_hwcap2 */
#endif
#define PSUIDFLAGS (SNOCD|SUGID)
+ #define RANDOM_LEN 16 /* 16 bytes for AT_RANDOM aux entry */
/*
* exece() - system call wrapper around exec_common()
*/
int
*** 295,312 ****
ua.fname = fname;
ua.argp = argp;
ua.envp = envp;
! /* If necessary, brand this process before we start the exec. */
! if (brandme)
! brand_setbrand(p);
if ((error = gexec(&vp, &ua, &args, NULL, 0, &execsz,
! exec_file, p->p_cred, brand_action)) != 0) {
! if (brandme)
! brand_clearbrand(p, B_FALSE);
VN_RELE(vp);
if (dir != NULL)
VN_RELE(dir);
pn_free(&resolvepn);
goto fail;
--- 297,343 ----
ua.fname = fname;
ua.argp = argp;
ua.envp = envp;
! /* If necessary, brand this process/lwp before we start the exec. */
! if (brandme) {
! void *brand_data = NULL;
+ /*
+ * Process branding may fail if multiple LWPs are present and
+ * holdlwps() cannot complete successfully.
+ */
+ error = brand_setbrand(p, B_TRUE);
+
+ if (error == 0 && BROP(p)->b_lwpdata_alloc != NULL) {
+ brand_data = BROP(p)->b_lwpdata_alloc(p);
+ if (brand_data == NULL) {
+ error = 1;
+ }
+ }
+
+ if (error == 0) {
+ mutex_enter(&p->p_lock);
+ BROP(p)->b_initlwp(lwp, brand_data);
+ mutex_exit(&p->p_lock);
+ } else {
+ VN_RELE(vp);
+ if (dir != NULL) {
+ VN_RELE(dir);
+ }
+ pn_free(&resolvepn);
+ goto fail;
+ }
+ }
+
if ((error = gexec(&vp, &ua, &args, NULL, 0, &execsz,
! exec_file, p->p_cred, &brand_action)) != 0) {
! if (brandme) {
! BROP(p)->b_freelwp(lwp);
! brand_clearbrand(p, B_TRUE);
! }
VN_RELE(vp);
if (dir != NULL)
VN_RELE(dir);
pn_free(&resolvepn);
goto fail;
*** 334,344 ****
curthread->t_predcache = NULL;
/*
* Clear contract template state
*/
! lwp_ctmpl_clear(lwp);
/*
* Save the directory in which we found the executable for expanding
* the %d token used in core file patterns.
*/
--- 365,375 ----
curthread->t_predcache = NULL;
/*
* Clear contract template state
*/
! lwp_ctmpl_clear(lwp, B_TRUE);
/*
* Save the directory in which we found the executable for expanding
* the %d token used in core file patterns.
*/
*** 358,367 ****
--- 389,400 ----
* restart system calls; the new program's environment should
* not be affected by detritus from the old program. Any
* pending held signals remain held, so don't clear t_hold.
*/
mutex_enter(&p->p_lock);
+ DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+ uintptr_t, lwp->lwp_oldcontext, uintptr_t, 0);
lwp->lwp_oldcontext = 0;
lwp->lwp_ustack = 0;
lwp->lwp_old_stk_ctl = 0;
sigemptyset(&up->u_signodefer);
sigemptyset(&up->u_sigonstack);
*** 417,428 ****
*/
close_exec(P_FINFO(p));
TRACE_2(TR_FAC_PROC, TR_PROC_EXEC, "proc_exec:p %p up %p", p, up);
/* Unbrand ourself if necessary. */
! if (PROC_IS_BRANDED(p) && (brand_action == EBA_NATIVE))
brand_clearbrand(p, B_FALSE);
setregs(&args);
/* Mark this as an executable vnode */
mutex_enter(&vp->v_lock);
--- 450,463 ----
*/
close_exec(P_FINFO(p));
TRACE_2(TR_FAC_PROC, TR_PROC_EXEC, "proc_exec:p %p up %p", p, up);
/* Unbrand ourself if necessary. */
! if (PROC_IS_BRANDED(p) && (brand_action == EBA_NATIVE)) {
! BROP(p)->b_freelwp(lwp);
brand_clearbrand(p, B_FALSE);
+ }
setregs(&args);
/* Mark this as an executable vnode */
mutex_enter(&vp->v_lock);
*** 542,552 ****
struct intpdata *idatap,
int level,
long *execsz,
caddr_t exec_file,
struct cred *cred,
! int brand_action)
{
struct vnode *vp, *execvp = NULL;
proc_t *pp = ttoproc(curthread);
struct execsw *eswp;
int error = 0;
--- 577,587 ----
struct intpdata *idatap,
int level,
long *execsz,
caddr_t exec_file,
struct cred *cred,
! int *brand_action)
{
struct vnode *vp, *execvp = NULL;
proc_t *pp = ttoproc(curthread);
struct execsw *eswp;
int error = 0;
*** 856,867 ****
* invalidate the associated /proc vnode.
*/
if (pp->p_plist || (pp->p_proc_flag & P_PR_TRACE))
args->traceinval = 1;
}
! if (pp->p_proc_flag & P_PR_PTRACE)
psignal(pp, SIGTRAP);
if (args->traceinval)
prinvalidate(&pp->p_user);
}
if (execvp)
VN_RELE(execvp);
--- 891,908 ----
* invalidate the associated /proc vnode.
*/
if (pp->p_plist || (pp->p_proc_flag & P_PR_TRACE))
args->traceinval = 1;
}
!
! /*
! * If legacy ptrace is enabled, generate the SIGTRAP.
! */
! if (pp->p_proc_flag & P_PR_PTRACE) {
psignal(pp, SIGTRAP);
+ }
+
if (args->traceinval)
prinvalidate(&pp->p_user);
}
if (execvp)
VN_RELE(execvp);
*** 1515,1525 ****
--- 1556,1585 ----
args->stk_strp += len;
return (0);
}
+ /*
+ * Add a fixed size byte array to the stack (only from kernel space).
+ */
static int
+ stk_byte_add(uarg_t *args, const uint8_t *sp, size_t len)
+ {
+ if (STK_AVAIL(args) < sizeof (int))
+ return (E2BIG);
+ *--args->stk_offp = args->stk_strp - args->stk_base;
+
+ if (len > STK_AVAIL(args))
+ return (E2BIG);
+ bcopy(sp, args->stk_strp, len);
+
+ args->stk_strp += len;
+
+ return (0);
+ }
+
+ static int
stk_getptr(uarg_t *args, char *src, char **dst)
{
int error;
if (args->from_model == DATAMODEL_NATIVE) {
*** 1551,1560 ****
--- 1611,1621 ----
int argv_empty = 0;
size_t ptrsize = args->from_ptrsize;
size_t size, pad;
char *argv = (char *)uap->argp;
char *envp = (char *)uap->envp;
+ uint8_t rdata[RANDOM_LEN];
/*
* Copy interpreter's name and argument to argv[0] and argv[1].
* In the rare case that we have nested interpreters then those names
* and arguments are also copied to the subsequent slots in argv.
*** 1633,1644 ****
}
args->na = (int *)(args->stk_base + args->stk_size) - args->stk_offp;
args->ne = args->na - argc;
/*
! * Add AT_SUN_PLATFORM, AT_SUN_EXECNAME, AT_SUN_BRANDNAME, and
! * AT_SUN_EMULATOR strings to the stack.
*/
if (auxvpp != NULL && *auxvpp != NULL) {
if ((error = stk_add(args, platform, UIO_SYSSPACE)) != 0)
return (error);
if ((error = stk_add(args, args->pathname, UIO_SYSSPACE)) != 0)
--- 1694,1706 ----
}
args->na = (int *)(args->stk_base + args->stk_size) - args->stk_offp;
args->ne = args->na - argc;
/*
! * Add AT_SUN_PLATFORM, AT_SUN_EXECNAME, AT_SUN_BRANDNAME,
! * AT_SUN_BRAND_NROOT, and AT_SUN_EMULATOR strings, as well as AT_RANDOM
! * array, to the stack.
*/
if (auxvpp != NULL && *auxvpp != NULL) {
if ((error = stk_add(args, platform, UIO_SYSSPACE)) != 0)
return (error);
if ((error = stk_add(args, args->pathname, UIO_SYSSPACE)) != 0)
*** 1647,1656 ****
--- 1709,1732 ----
(error = stk_add(args, args->brandname, UIO_SYSSPACE)) != 0)
return (error);
if (args->emulator != NULL &&
(error = stk_add(args, args->emulator, UIO_SYSSPACE)) != 0)
return (error);
+
+ /*
+ * For the AT_RANDOM aux vector we provide 16 bytes of random
+ * data.
+ */
+ (void) random_get_pseudo_bytes(rdata, sizeof (rdata));
+
+ if ((error = stk_byte_add(args, rdata, sizeof (rdata))) != 0)
+ return (error);
+
+ if (args->brand_nroot != NULL &&
+ (error = stk_add(args, args->brand_nroot,
+ UIO_SYSSPACE)) != 0)
+ return (error);
}
/*
* Compute the size of the stack. This includes all the pointers,
* the space reserved for the aux vector, and all the strings.
*** 1753,1763 ****
return (-1);
/*
* Fill in the aux vector now that we know the user stack addresses
* for the AT_SUN_PLATFORM, AT_SUN_EXECNAME, AT_SUN_BRANDNAME and
! * AT_SUN_EMULATOR strings.
*/
if (auxvpp != NULL && *auxvpp != NULL) {
if (args->to_model == DATAMODEL_NATIVE) {
auxv_t **a = (auxv_t **)auxvpp;
ADDAUX(*a, AT_SUN_PLATFORM, (long)&ustrp[*--offp])
--- 1829,1839 ----
return (-1);
/*
* Fill in the aux vector now that we know the user stack addresses
* for the AT_SUN_PLATFORM, AT_SUN_EXECNAME, AT_SUN_BRANDNAME and
! * AT_SUN_EMULATOR strings, as well as the AT_RANDOM array.
*/
if (auxvpp != NULL && *auxvpp != NULL) {
if (args->to_model == DATAMODEL_NATIVE) {
auxv_t **a = (auxv_t **)auxvpp;
ADDAUX(*a, AT_SUN_PLATFORM, (long)&ustrp[*--offp])
*** 1766,1775 ****
--- 1842,1856 ----
ADDAUX(*a,
AT_SUN_BRANDNAME, (long)&ustrp[*--offp])
if (args->emulator != NULL)
ADDAUX(*a,
AT_SUN_EMULATOR, (long)&ustrp[*--offp])
+ ADDAUX(*a, AT_RANDOM, (long)&ustrp[*--offp])
+ if (args->brand_nroot != NULL) {
+ ADDAUX(*a,
+ AT_SUN_BRAND_NROOT, (long)&ustrp[*--offp])
+ }
} else {
auxv32_t **a = (auxv32_t **)auxvpp;
ADDAUX(*a,
AT_SUN_PLATFORM, (int)(uintptr_t)&ustrp[*--offp])
ADDAUX(*a,
*** 1778,1789 ****
--- 1859,1875 ----
ADDAUX(*a, AT_SUN_BRANDNAME,
(int)(uintptr_t)&ustrp[*--offp])
if (args->emulator != NULL)
ADDAUX(*a, AT_SUN_EMULATOR,
(int)(uintptr_t)&ustrp[*--offp])
+ ADDAUX(*a, AT_RANDOM, (int)(uintptr_t)&ustrp[*--offp])
+ if (args->brand_nroot != NULL) {
+ ADDAUX(*a, AT_SUN_BRAND_NROOT,
+ (int)(uintptr_t)&ustrp[*--offp])
}
}
+ }
return (0);
}
/*
*** 1866,1875 ****
--- 1952,1964 ----
args->ncargs = NCARGS32;
args->stk_align = STACK_ALIGN32;
usrstack = (char *)USRSTACK32;
}
+ if (args->maxstack != 0 && (uintptr_t)usrstack > args->maxstack)
+ usrstack = (char *)args->maxstack;
+
ASSERT(P2PHASE((uintptr_t)usrstack, args->stk_align) == 0);
#if defined(__sparc)
/*
* Make sure user register windows are empty before