FreeBSD/sys/amd64/linux/linux_sysvec.c
/*
 * Copy strings out to the new process address space, constructing new arg
 * and env vector tables. Return a pointer to the base so that it can be used
 * as the initial stack pointer.
 */
Copy strings out to the new process address space, constructing new arg
and env vector tables. Return a pointer to the base so that it can be used
as the initial stack pointer.
Copy strings out to the new process address space constructing new arg and env vector tables . Return a pointer to the base so that it can be used as the initial stack pointer .
static register_t *
linux_copyout_strings(struct image_params *imgp)
{
	int argc, envc;
	char **vectp;
	char *stringp, *destp;
	register_t *stack_base;
	struct ps_strings *arginfo;
	char canary[LINUX_AT_RANDOM_LEN];
	size_t execpath_len;
	struct proc *p;
	if (imgp->execpath != NULL && imgp->auxargs != NULL)
		execpath_len = strlen(imgp->execpath) + 1;
	else
		execpath_len = 0;
	p = imgp->proc;
	arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
	destp =	(caddr_t)arginfo - SPARE_USRSPACE -
	    roundup(sizeof(canary), sizeof(char *)) -
	    roundup(execpath_len, sizeof(char *)) -
	    roundup(ARG_MAX - imgp->args->stringspace, sizeof(char *));
	if (execpath_len != 0) {
		imgp->execpathp = (uintptr_t)arginfo - execpath_len;
		copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len);
	}
	arc4rand(canary, sizeof(canary), 0);
	imgp->canary = (uintptr_t)arginfo -
	    roundup(execpath_len, sizeof(char *)) -
	    roundup(sizeof(canary), sizeof(char *));
	copyout(canary, (void *)imgp->canary, sizeof(canary));
	if (imgp->auxargs) {
		imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
		    (LINUX_AT_COUNT * 2);
		vectp = (char **)(destp - (imgp->args->argc +
		    imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));
	} else {
		vectp = (char **)(destp - (imgp->args->argc +
		    imgp->args->envc + 2) * sizeof(char *));
	}
	stack_base = (register_t *)vectp;
	stringp = imgp->args->begin_argv;
	argc = imgp->args->argc;
	envc = imgp->args->envc;
	copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
	suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nargvstr, argc);
	for (; argc > 0; --argc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}
	suword(vectp++, 0);
	suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
	suword(&arginfo->ps_nenvstr, envc);
	for (; envc > 0; --envc) {
		suword(vectp++, (long)(intptr_t)destp);
		while (*stringp++ != 0)
			destp++;
		destp++;
	}
	suword(vectp, 0);
	return (stack_base);
}
static register_t * linux_copyout_strings ( struct image_params * imgp ) { int argc , envc ; char * * vectp ; char * stringp , * destp ; register_t * stack_base ; struct ps_strings * arginfo ; char canary [ LINUX_AT_RANDOM_LEN ] ; size_t execpath_len ; struct proc * p ; if ( imgp -> execpath != NULL && imgp -> auxargs != NULL ) execpath_len = strlen ( imgp -> execpath ) + 1 ; else execpath_len = 0 ; p = imgp -> proc ; arginfo = ( struct ps_strings * ) p -> p_sysent -> sv_psstrings ; destp = ( caddr_t ) arginfo - SPARE_USRSPACE - roundup ( sizeof ( canary ) , sizeof ( char * ) ) - roundup ( execpath_len , sizeof ( char * ) ) - roundup ( ARG_MAX - imgp -> args -> stringspace , sizeof ( char * ) ) ; if ( execpath_len != 0 ) { imgp -> execpathp = ( uintptr_t ) arginfo - execpath_len ; copyout ( imgp -> execpath , ( void * ) imgp -> execpathp , execpath_len ) ; } arc4rand ( canary , sizeof ( canary ) , 0 ) ; imgp -> canary = ( uintptr_t ) arginfo - roundup ( execpath_len , sizeof ( char * ) ) - roundup ( sizeof ( canary ) , sizeof ( char * ) ) ; copyout ( canary , ( void * ) imgp -> canary , sizeof ( canary ) ) ; if ( imgp -> auxargs ) { imgp -> auxarg_size = ( imgp -> auxarg_size ) ? imgp -> auxarg_size : ( LINUX_AT_COUNT * 2 ) ; vectp = ( char * * ) ( destp - ( imgp -> args -> argc + imgp -> args -> envc + 2 + imgp -> auxarg_size ) * sizeof ( char * ) ) ; } else { vectp = ( char * * ) ( destp - ( imgp -> args -> argc + imgp -> args -> envc + 2 ) * sizeof ( char * ) ) ; } stack_base = ( register_t * ) vectp ; stringp = imgp -> args -> begin_argv ; argc = imgp -> args -> argc ; envc = imgp -> args -> envc ; copyout ( stringp , destp , ARG_MAX - imgp -> args -> stringspace ) ; suword ( & arginfo -> ps_argvstr , ( long ) ( intptr_t ) vectp ) ; suword ( & arginfo -> ps_nargvstr , argc ) ; for ( ; argc > 0 ; -- argc ) { suword ( vectp ++ , ( long ) ( intptr_t ) destp ) ; while ( * stringp ++ != 0 ) destp ++ ; destp ++ ; } suword ( vectp ++ , 0 ) ; suword ( & arginfo -> ps_envstr , ( long ) ( intptr_t ) vectp ) ; suword ( & arginfo -> ps_nenvstr , envc ) ; for ( ; envc > 0 ; -- envc ) { suword ( vectp ++ , ( long ) ( intptr_t ) destp ) ; while ( * stringp ++ != 0 ) destp ++ ; destp ++ ; } suword ( vectp , 0 ) ; return ( stack_base ) ; }
Copy strings out to the new process address space, constructing new arg
 and env vector tables.
Copy strings out to the new process address space constructing new arg and env vector tables .
/*
	 * Calculate string base and vector table pointers.
	 */ /*
	 * Prepare the canary for SSP.
	 */ /*
	 * If we have a valid auxargs ptr, prepare some room
	 * on the stack.
	 */ /*
		 * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
		 * lower compatibility.
		 */ /*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets,and imgp->auxarg_size is room
		 * for argument of Runtime loader.
		 */ /*
		 * The '+ 2' is for the null pointers at the end of each of
		 * the arg and env vector sets
		 */ /*
	 * vectp also becomes our initial stack base
	 */ /*
	 * Copy out strings - arguments and environment.
	 */ /*
	 * Fill in "ps_strings" struct for ps, w, etc.
	 */ /*
	 * Fill in argument portion of vector table.
	 */ /* a null vector table pointer separates the argp's from the envp's */ /*
	 * Fill in environment portion of vector table.
	 */ /* end of vector table is a null pointer */