diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 9d8196d..aaf86d8 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -115,7 +115,8 @@ SET_DECLARE(linux_device_handler_set, st static int elf_linux_fixup(register_t **stack_base, struct image_params *iparams); -static register_t *linux_copyout_strings(struct image_params *imgp); +static register_t *linux_copyout_strings(struct image_params *imgp, + vm_offset_t *uargs); static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params); static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); @@ -849,7 +850,7 @@ exec_linux_setregs(td, entry, stack, ps_ * XXX copied from ia32_sysvec.c. */ static register_t * -linux_copyout_strings(struct image_params *imgp) +linux_copyout_strings(struct image_params *imgp, vm_offset_t *uargs) { int argc, envc; u_int32_t *vectp; diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 8db17d5..c672e08 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -93,7 +93,8 @@ CTASSERT(sizeof(struct ia32_ucontext4) = CTASSERT(sizeof(struct ia32_sigframe4) == 408); #endif -static register_t *ia32_copyout_strings(struct image_params *imgp); +static register_t *ia32_copyout_strings(struct image_params *imgp, + vm_offset_t *uargs); static void ia32_fixlimits(struct proc *p); extern struct sysent freebsd32_sysent[]; @@ -170,7 +171,7 @@ elf32_dump_thread(struct thread *td __un /* XXX may be freebsd32 MI */ static register_t * -ia32_copyout_strings(struct image_params *imgp) +ia32_copyout_strings(struct image_params *imgp, vm_offset_t *uargs) { int argc, envc; u_int32_t *vectp; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index cb4449b..4c8f854 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -304,6 +304,7 @@ do_execve(td, args, mac_p) #ifdef HWPMC_HOOKS struct pmckern_procexec pe; #endif + vm_offset_t uargs = 0; vfslocked = 0; imgp = &image_params; @@ -456,9 +457,9 @@ interpret: * Copy out strings (args and env) and initialize stack base */ if (p->p_sysent->sv_copyout_strings) - stack_base = (*p->p_sysent->sv_copyout_strings)(imgp); + stack_base = (*p->p_sysent->sv_copyout_strings)(imgp, &uargs); else - stack_base = exec_copyout_strings(imgp); + stack_base = exec_copyout_strings(imgp, &uargs); /* * If custom stack fixup routine present for this process @@ -487,6 +488,8 @@ interpret: newargs = pargs_alloc(i); bcopy(imgp->args->begin_argv, newargs->ar_args, i); } + p->p_uargs = uargs; + p->p_uargslen = i; /* close files on exec */ VOP_UNLOCK(imgp->vp, 0, td); @@ -1058,8 +1061,7 @@ exec_free_args(struct image_args *args) * as the initial stack pointer. */ register_t * -exec_copyout_strings(imgp) - struct image_params *imgp; +exec_copyout_strings(struct image_params *imgp, vm_offset_t *uargs) { int argc, envc; char **vectp; @@ -1126,6 +1128,8 @@ exec_copyout_strings(imgp) argc = imgp->args->argc; envc = imgp->args->envc; + *uargs = (vm_offset_t)destp; + /* * Copy out strings - arguments and environment. */ diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 02568bb..d13eac6 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -54,10 +54,11 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_pr #include #include #include -#ifdef KTRACE #include +#ifdef KTRACE #include #endif +#include #include #include @@ -1157,6 +1158,9 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARG u_int namelen = arg2; struct pargs *newpa, *pa; struct proc *p; + struct uio uio; + struct iovec iov; + char *args = NULL; int error = 0; if (namelen != 1) @@ -1179,8 +1183,33 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARG pa = p->p_args; pargs_hold(pa); PROC_UNLOCK(p); - if (req->oldptr != NULL && pa != NULL) - error = SYSCTL_OUT(req, pa->ar_args, pa->ar_length); + + if (p->p_uargs != 0) { + args = malloc(p->p_uargslen, M_TEMP, M_WAITOK); + iov.iov_base = args; + iov.iov_len = p->p_uargslen; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = p->p_uargs; + uio.uio_resid = p->p_uargslen; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + uio.uio_td = curthread; + + error = proc_rwmem(p, &uio); + if (error != 0) { + printf("proc_rwmem returned %d\n", error); + pargs_drop(pa); + return (error); + } + + if (req->oldptr != NULL && pa != NULL) + error = SYSCTL_OUT(req, args, p->p_uargslen); + free(args, M_TEMP); + } else { + if (req->oldptr != NULL && pa != NULL) + error = SYSCTL_OUT(req, args, p->p_uargslen); + } pargs_drop(pa); if (error != 0 || req->newptr == NULL) return (error); diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h index 31a6265..72aa084 100644 --- a/sys/sys/imgact.h +++ b/sys/sys/imgact.h @@ -71,7 +71,7 @@ struct sysentvec; struct thread; int exec_check_permissions(struct image_params *); -register_t *exec_copyout_strings(struct image_params *); +register_t *exec_copyout_strings(struct image_params *, vm_offset_t *); int exec_new_vmspace(struct image_params *, struct sysentvec *); void exec_setregs(struct thread *, u_long, u_long, u_long); int exec_shell_imgact(struct image_params *); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 17c87ab..e8a8aa4 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -561,6 +561,8 @@ struct proc { struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */ struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */ struct pargs *p_args; /* (c) Process arguments. */ + vm_offset_t p_uargs; + u_int p_uargslen; rlim_t p_cpulimit; /* (j) Current CPU limit in seconds. */ signed char p_nice; /* (c + j) Process "nice" value. */ /* End area that is copied on creation. */ diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 7668be1..c6bcd69 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -96,7 +96,8 @@ struct sysentvec { vm_offset_t sv_usrstack; /* USRSTACK */ vm_offset_t sv_psstrings; /* PS_STRINGS */ int sv_stackprot; /* vm protection for stack */ - register_t *(*sv_copyout_strings)(struct image_params *); + register_t *(*sv_copyout_strings)(struct image_params *, + vm_offset_t *); void (*sv_setregs)(struct thread *, u_long, u_long, u_long); void (*sv_fixlimits)(struct proc *); };