Author: kib Date: Sun May 24 07:32:02 2015 New Revision: 283359 URL: https://svnweb.freebsd.org/changeset/base/283359
Log: MFC r282708: On exec, single-threading must be enforced before arguments space is allocated from exec_map. Modified: stable/10/sys/amd64/linux32/linux32_machdep.c stable/10/sys/compat/freebsd32/freebsd32_misc.c stable/10/sys/compat/svr4/svr4_misc.c stable/10/sys/i386/ibcs2/ibcs2_misc.c stable/10/sys/i386/linux/linux_machdep.c stable/10/sys/kern/kern_exec.c stable/10/sys/sys/imgact.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/linux32/linux32_machdep.c ============================================================================== --- stable/10/sys/amd64/linux32/linux32_machdep.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/amd64/linux32/linux32_machdep.c Sun May 24 07:32:02 2015 (r283359) @@ -137,6 +137,7 @@ int linux_execve(struct thread *td, struct linux_execve_args *args) { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; @@ -147,12 +148,17 @@ linux_execve(struct thread *td, struct l printf(ARGS(execve, "%s"), path); #endif + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp, args->envp); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); - if (error == 0) + if (error == 0) { /* Linux process can execute FreeBSD one, do not attempt * to create emuldata for such process using * linux_proc_init, this leads to a panic on KASSERT @@ -160,6 +166,8 @@ linux_execve(struct thread *td, struct l */ if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX) error = linux_proc_init(td, 0, 0); + } + post_execve(td, error, oldvmspace); return (error); } Modified: stable/10/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/10/sys/compat/freebsd32/freebsd32_misc.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/compat/freebsd32/freebsd32_misc.c Sun May 24 07:32:02 2015 (r283359) @@ -400,12 +400,17 @@ int freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) { struct image_args eargs; + struct vmspace *oldvmspace; int error; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, uap->argv, uap->envv); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } @@ -413,14 +418,19 @@ int freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap) { struct image_args eargs; + struct vmspace *oldvmspace; int error; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE, uap->argv, uap->envv); if (error == 0) { eargs.fd = uap->fd; error = kern_execve(td, &eargs, NULL); } + post_execve(td, error, oldvmspace); return (error); } Modified: stable/10/sys/compat/svr4/svr4_misc.c ============================================================================== --- stable/10/sys/compat/svr4/svr4_misc.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/compat/svr4/svr4_misc.c Sun May 24 07:32:02 2015 (r283359) @@ -167,15 +167,22 @@ svr4_sys_execv(td, uap) struct svr4_sys_execv_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } @@ -185,16 +192,23 @@ svr4_sys_execve(td, uap) struct svr4_sys_execve_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, uap->envp); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } Modified: stable/10/sys/i386/ibcs2/ibcs2_misc.c ============================================================================== --- stable/10/sys/i386/ibcs2/ibcs2_misc.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/i386/ibcs2/ibcs2_misc.c Sun May 24 07:32:02 2015 (r283359) @@ -200,15 +200,22 @@ ibcs2_execv(td, uap) struct ibcs2_execv_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } @@ -218,16 +225,23 @@ ibcs2_execve(td, uap) struct ibcs2_execve_args *uap; { struct image_args eargs; + struct vmspace *oldvmspace; char *path; int error; CHECKALTEXIST(td, uap->path, &path); + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(path, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, uap->envp); free(path, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); + post_execve(td, error, oldvmspace); return (error); } Modified: stable/10/sys/i386/linux/linux_machdep.c ============================================================================== --- stable/10/sys/i386/linux/linux_machdep.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/i386/linux/linux_machdep.c Sun May 24 07:32:02 2015 (r283359) @@ -126,9 +126,10 @@ bsd_to_linux_sigaltstack(int bsa) int linux_execve(struct thread *td, struct linux_execve_args *args) { - int error; - char *newpath; struct image_args eargs; + struct vmspace *oldvmspace; + char *newpath; + int error; LCONVPATHEXIST(td, args->path, &newpath); @@ -137,12 +138,17 @@ linux_execve(struct thread *td, struct l printf(ARGS(execve, "%s"), newpath); #endif + error = pre_execve(td, &oldvmspace); + if (error != 0) { + free(newpath, M_TEMP); + return (error); + } error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE, args->argp, args->envp); free(newpath, M_TEMP); if (error == 0) error = kern_execve(td, &eargs, NULL); - if (error == 0) + if (error == 0) { /* linux process can exec fbsd one, dont attempt * to create emuldata for such process using * linux_proc_init, this leads to a panic on KASSERT @@ -150,6 +156,8 @@ linux_execve(struct thread *td, struct l */ if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX) error = linux_proc_init(td, 0, 0); + } + post_execve(td, error, oldvmspace); return (error); } Modified: stable/10/sys/kern/kern_exec.c ============================================================================== --- stable/10/sys/kern/kern_exec.c Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/kern/kern_exec.c Sun May 24 07:32:02 2015 (r283359) @@ -196,21 +196,20 @@ struct execve_args { #endif int -sys_execve(td, uap) - struct thread *td; - struct execve_args /* { - char *fname; - char **argv; - char **envv; - } */ *uap; +sys_execve(struct thread *td, struct execve_args *uap) { - int error; struct image_args args; + struct vmspace *oldvmspace; + int error; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE, uap->argv, uap->envv); if (error == 0) error = kern_execve(td, &args, NULL); + post_execve(td, error, oldvmspace); return (error); } @@ -224,15 +223,20 @@ struct fexecve_args { int sys_fexecve(struct thread *td, struct fexecve_args *uap) { - int error; struct image_args args; + struct vmspace *oldvmspace; + int error; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); error = exec_copyin_args(&args, NULL, UIO_SYSSPACE, uap->argv, uap->envv); if (error == 0) { args.fd = uap->fd; error = kern_execve(td, &args, NULL); } + post_execve(td, error, oldvmspace); return (error); } @@ -246,65 +250,56 @@ struct __mac_execve_args { #endif int -sys___mac_execve(td, uap) - struct thread *td; - struct __mac_execve_args /* { - char *fname; - char **argv; - char **envv; - struct mac *mac_p; - } */ *uap; +sys___mac_execve(struct thread *td, struct __mac_execve_args *uap) { #ifdef MAC - int error; struct image_args args; + struct vmspace *oldvmspace; + int error; + error = pre_execve(td, &oldvmspace); + if (error != 0) + return (error); error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE, uap->argv, uap->envv); if (error == 0) error = kern_execve(td, &args, uap->mac_p); + post_execve(td, error, oldvmspace); return (error); #else return (ENOSYS); #endif } -/* - * XXX: kern_execve has the astonishing property of not always returning to - * the caller. If sufficiently bad things happen during the call to - * do_execve(), it can end up calling exit1(); as a result, callers must - * avoid doing anything which they might need to undo (e.g., allocating - * memory). - */ int -kern_execve(td, args, mac_p) - struct thread *td; - struct image_args *args; - struct mac *mac_p; +pre_execve(struct thread *td, struct vmspace **oldvmspace) { - struct proc *p = td->td_proc; - struct vmspace *oldvmspace; + struct proc *p; int error; - AUDIT_ARG_ARGV(args->begin_argv, args->argc, - args->begin_envv - args->begin_argv); - AUDIT_ARG_ENVV(args->begin_envv, args->envc, - args->endp - args->begin_envv); - if (p->p_flag & P_HADTHREADS) { + KASSERT(td == curthread, ("non-current thread %p", td)); + error = 0; + p = td->td_proc; + if ((p->p_flag & P_HADTHREADS) != 0) { PROC_LOCK(p); - if (thread_single(p, SINGLE_BOUNDARY)) { - PROC_UNLOCK(p); - exec_free_args(args); - return (ERESTART); /* Try again later. */ - } + if (thread_single(p, SINGLE_BOUNDARY) != 0) + error = ERESTART; PROC_UNLOCK(p); } + KASSERT(error != 0 || (td->td_pflags & TDP_EXECVMSPC) == 0, + ("nested execve")); + *oldvmspace = p->p_vmspace; + return (error); +} - KASSERT((td->td_pflags & TDP_EXECVMSPC) == 0, ("nested execve")); - oldvmspace = td->td_proc->p_vmspace; - error = do_execve(td, args, mac_p); +void +post_execve(struct thread *td, int error, struct vmspace *oldvmspace) +{ + struct proc *p; - if (p->p_flag & P_HADTHREADS) { + KASSERT(td == curthread, ("non-current thread %p", td)); + p = td->td_proc; + if ((p->p_flag & P_HADTHREADS) != 0) { PROC_LOCK(p); /* * If success, we upgrade to SINGLE_EXIT state to @@ -317,13 +312,29 @@ kern_execve(td, args, mac_p) PROC_UNLOCK(p); } if ((td->td_pflags & TDP_EXECVMSPC) != 0) { - KASSERT(td->td_proc->p_vmspace != oldvmspace, + KASSERT(p->p_vmspace != oldvmspace, ("oldvmspace still used")); vmspace_free(oldvmspace); td->td_pflags &= ~TDP_EXECVMSPC; } +} - return (error); +/* + * XXX: kern_execve has the astonishing property of not always returning to + * the caller. If sufficiently bad things happen during the call to + * do_execve(), it can end up calling exit1(); as a result, callers must + * avoid doing anything which they might need to undo (e.g., allocating + * memory). + */ +int +kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p) +{ + + AUDIT_ARG_ARGV(args->begin_argv, args->argc, + args->begin_envv - args->begin_argv); + AUDIT_ARG_ENVV(args->begin_envv, args->envc, + args->endp - args->begin_envv); + return (do_execve(td, args, mac_p)); } /* Modified: stable/10/sys/sys/imgact.h ============================================================================== --- stable/10/sys/sys/imgact.h Sun May 24 07:23:16 2015 (r283358) +++ stable/10/sys/sys/imgact.h Sun May 24 07:32:02 2015 (r283359) @@ -86,6 +86,7 @@ struct image_params { #ifdef _KERNEL struct sysentvec; struct thread; +struct vmspace; #define IMGACT_CORE_COMPRESS 0x01 @@ -98,6 +99,8 @@ void exec_setregs(struct thread *, struc int exec_shell_imgact(struct image_params *); int exec_copyin_args(struct image_args *, char *, enum uio_seg, char **, char **); +int pre_execve(struct thread *td, struct vmspace **oldvmspace); +void post_execve(struct thread *td, int error, struct vmspace *oldvmspace); #endif #endif /* !_SYS_IMGACT_H_ */ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"