diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-08-03 16:11:32 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2011-08-03 16:11:32 +0000 |
commit | c521aa1be51fe6cf5c467fd0dd8c63377aa82f83 (patch) | |
tree | dbdc126a15d9488fa08d66bc893d717579946750 | |
parent | bd7ebeca9ddd78842746f38aa29b57d1c8305add (diff) |
Fix linux compat breakage: can't copyin() from kernel-space, so
move that out of i386_set_threadbase(), and have clone() pass NULL
to fork1() for the child func argument so that it gets the child
proc pointer.
Report and verification by pirofti@, heavy lifting by matthew@
-rw-r--r-- | sys/arch/i386/i386/linux_machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/i386/sys_machdep.c | 27 | ||||
-rw-r--r-- | sys/arch/i386/include/sysarch.h | 4 | ||||
-rw-r--r-- | sys/compat/linux/linux_sched.c | 7 |
4 files changed, 23 insertions, 19 deletions
diff --git a/sys/arch/i386/i386/linux_machdep.c b/sys/arch/i386/i386/linux_machdep.c index 96b0ecb52e3..c9c8a5c5b00 100644 --- a/sys/arch/i386/i386/linux_machdep.c +++ b/sys/arch/i386/i386/linux_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_machdep.c,v 1.40 2011/07/05 04:48:01 guenther Exp $ */ +/* $OpenBSD: linux_machdep.c,v 1.41 2011/08/03 16:11:31 guenther Exp $ */ /* $NetBSD: linux_machdep.c,v 1.29 1996/05/03 19:42:11 christos Exp $ */ /* @@ -653,7 +653,7 @@ linux_sys_set_thread_area(struct proc *p, void *v, register_t *retval) } else if (ldesc.entry_number != GUGS_SEL) return EINVAL; - return i386_set_threadbase(p, &SCARG(uap, desc)->base_addr, TSEG_GS); + return i386_set_threadbase(p, SCARG(uap, desc)->base_addr, TSEG_GS); } int diff --git a/sys/arch/i386/i386/sys_machdep.c b/sys/arch/i386/i386/sys_machdep.c index cfc7827c347..0289edbaf0b 100644 --- a/sys/arch/i386/i386/sys_machdep.c +++ b/sys/arch/i386/i386/sys_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_machdep.c,v 1.29 2011/04/15 15:08:19 chl Exp $ */ +/* $OpenBSD: sys_machdep.c,v 1.30 2011/08/03 16:11:31 guenther Exp $ */ /* $NetBSD: sys_machdep.c,v 1.28 1996/05/03 19:42:29 christos Exp $ */ /*- @@ -72,8 +72,6 @@ extern struct vm_map *kernel_map; int i386_iopl(struct proc *, void *, register_t *); int i386_get_ioperm(struct proc *, void *, register_t *); int i386_set_ioperm(struct proc *, void *, register_t *); -int i386_get_threadbase(struct proc *, void *, int); -int i386_set_threadbase(struct proc *, void *, int); #ifdef USER_LDT @@ -405,15 +403,10 @@ i386_get_threadbase(struct proc *p, void *args, int which) } int -i386_set_threadbase(struct proc *p, void *args, int which) +i386_set_threadbase(struct proc *p, uint32_t base, int which) { - int error; - uint32_t base; struct segment_descriptor *sdp; - if ((error = copyin(args, &base, sizeof(base))) != 0) - return error; - /* * We can't place a limit on the segment used by the library * thread register (%gs) because the ELF ABI for i386 places @@ -472,16 +465,28 @@ sys_sysarch(struct proc *p, void *v, register_t *retval) break; case I386_SET_FSBASE: - error = i386_set_threadbase(p, SCARG(uap, parms), TSEG_FS); + { + uint32_t base; + + if ((error = copyin(SCARG(uap, parms), &base, sizeof(base)))) + break; + error = i386_set_threadbase(p, base, TSEG_FS); break; + } case I386_GET_GSBASE: error = i386_get_threadbase(p, SCARG(uap, parms), TSEG_GS); break; case I386_SET_GSBASE: - error = i386_set_threadbase(p, SCARG(uap, parms), TSEG_GS); + { + uint32_t base; + + if ((error = copyin(SCARG(uap, parms), &base, sizeof(base)))) + break; + error = i386_set_threadbase(p, base, TSEG_GS); break; + } default: error = EINVAL; diff --git a/sys/arch/i386/include/sysarch.h b/sys/arch/i386/include/sysarch.h index 04e50fab3bd..116325310cd 100644 --- a/sys/arch/i386/include/sysarch.h +++ b/sys/arch/i386/include/sysarch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysarch.h,v 1.8 2011/04/04 21:50:41 pirofti Exp $ */ +/* $OpenBSD: sysarch.h,v 1.9 2011/08/03 16:11:31 guenther Exp $ */ /* $NetBSD: sysarch.h,v 1.8 1996/01/08 13:51:44 mycroft Exp $ */ #ifndef _MACHINE_SYSARCH_H_ @@ -55,7 +55,7 @@ int i386_set_gsbase(void *); int sysarch(int, void *); #else int i386_get_threadbase(struct proc *, void *, int); -int i386_set_threadbase(struct proc *, void *, int); +int i386_set_threadbase(struct proc *, uint32_t, int); #endif #endif /* !_MACHINE_SYSARCH_H_ */ diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c index 61a4b5b98ad..14b00c23bf8 100644 --- a/sys/compat/linux/linux_sched.c +++ b/sys/compat/linux/linux_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_sched.c,v 1.10 2011/04/05 15:44:40 pirofti Exp $ */ +/* $OpenBSD: linux_sched.c,v 1.11 2011/08/03 16:11:31 guenther Exp $ */ /* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */ /*- @@ -177,7 +177,7 @@ linux_sys_clone(struct proc *p, void *v, register_t *retval) * that makes this adjustment is a noop. */ error = fork1(p, sig, flags, SCARG(uap, stack), 0, linux_child_return, - p, retval, NULL); + NULL, retval, NULL); if (error) return error; @@ -407,8 +407,7 @@ linux_child_return(void *arg) struct proc *p = (struct proc *)arg; struct linux_emuldata *emul = p->p_emuldata; - if (i386_set_threadbase(p, &emul->my_tls_base, TSEG_GS)) - return; + i386_set_threadbase(p, emul->my_tls_base, TSEG_GS); if (emul->my_set_tid) { pid_t pid = p->p_pid + THREAD_PID_OFFSET; |