Index: sys/arch/amd64/amd64/netbsd32_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/amd64/netbsd32_machdep.c,v retrieving revision 1.96 diff -u -p -r1.96 netbsd32_machdep.c --- sys/arch/amd64/amd64/netbsd32_machdep.c 2 Sep 2016 07:51:05 -0000 1.96 +++ sys/arch/amd64/amd64/netbsd32_machdep.c 15 Oct 2016 12:40:13 -0000 @@ -487,12 +487,12 @@ netbsd32_process_read_regs(struct lwp *l { struct trapframe *tf = l->l_md.md_regs; - regs->r_gs = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_fs = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_es = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_ds = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_eflags = tf->tf_rflags; /* XXX avoid sign extension problems with unknown upper bits? */ + regs->r_gs = tf->tf_gs & 0xffff; + regs->r_fs = tf->tf_fs & 0xffff; + regs->r_es = tf->tf_es & 0xffff; + regs->r_ds = tf->tf_ds & 0xffff; + regs->r_eflags = tf->tf_rflags; regs->r_edi = tf->tf_rdi & 0xffffffff; regs->r_esi = tf->tf_rsi & 0xffffffff; regs->r_ebp = tf->tf_rbp & 0xffffffff; @@ -501,9 +501,9 @@ netbsd32_process_read_regs(struct lwp *l regs->r_ecx = tf->tf_rcx & 0xffffffff; regs->r_eax = tf->tf_rax & 0xffffffff; regs->r_eip = tf->tf_rip & 0xffffffff; - regs->r_cs = tf->tf_cs; + regs->r_cs = tf->tf_cs & 0xffff; regs->r_esp = tf->tf_rsp & 0xffffffff; - regs->r_ss = tf->tf_ss; + regs->r_ss = tf->tf_ss & 0xffff; return (0); } @@ -511,22 +511,52 @@ netbsd32_process_read_regs(struct lwp *l int netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz) { - struct fpreg regs64; - int error; - size_t fp_size; + + __CTASSERT(sizeof *regs == sizeof (struct save87)); + process_read_fpregs_s87(l, (struct save87 *)regs); + return 0; +} + +int +netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) +{ + struct trapframe *tf = l->l_md.md_regs; /* - * All that stuff makes no sense in i386 code :( + * Check for security violations. Taken from i386/process_machdep.c. */ + if (((regs->r_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || + !VALID_USER_CSEL32(regs->r_cs)) + return EINVAL; - fp_size = sizeof regs64; - error = process_read_fpregs(l, ®s64, &fp_size); - if (error) - return error; - __CTASSERT(sizeof *regs == sizeof (struct save87)); - process_xmm_to_s87(®s64.fxstate, (struct save87 *)regs); + tf->tf_rax = regs->r_eax; + tf->tf_rcx = regs->r_ecx; + tf->tf_rdx = regs->r_edx; + tf->tf_rbx = regs->r_ebx; + tf->tf_rsp = regs->r_esp; + tf->tf_rbp = regs->r_ebp; + tf->tf_rsi = regs->r_esi; + tf->tf_rdi = regs->r_edi; + tf->tf_rip = regs->r_eip; + tf->tf_rflags = regs->r_eflags; + tf->tf_cs = regs->r_cs; + tf->tf_ss = regs->r_ss; + tf->tf_ds = regs->r_ds; + tf->tf_es = regs->r_es; + tf->tf_fs = regs->r_fs; + tf->tf_gs = regs->r_gs; - return (0); + return 0; +} + +int +netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs, + size_t sz) +{ + + __CTASSERT(sizeof *regs == sizeof (struct save87)); + process_write_fpregs_s87(l, (const struct save87 *)regs); + return 0; } int Index: sys/arch/amd64/include/netbsd32_machdep.h =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/include/netbsd32_machdep.h,v retrieving revision 1.19 diff -u -p -r1.19 netbsd32_machdep.h --- sys/arch/amd64/include/netbsd32_machdep.h 7 Feb 2014 22:40:22 -0000 1.19 +++ sys/arch/amd64/include/netbsd32_machdep.h 15 Oct 2016 12:40:13 -0000 @@ -138,4 +138,7 @@ struct x86_64_set_mtrr_args32 { int netbsd32_process_read_regs(struct lwp *, struct reg32 *); int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); +int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); +int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); + #endif /* _MACHINE_NETBSD32_H_ */ Index: sys/arch/amd64/include/ptrace.h =================================================================== RCS file: /cvsroot/src/sys/arch/amd64/include/ptrace.h,v retrieving revision 1.6 diff -u -p -r1.6 ptrace.h --- sys/arch/amd64/include/ptrace.h 25 Sep 2015 16:05:17 -0000 1.6 +++ sys/arch/amd64/include/ptrace.h 15 Oct 2016 12:40:13 -0000 @@ -68,6 +68,9 @@ #define process_read_regs32 netbsd32_process_read_regs #define process_read_fpregs32 netbsd32_process_read_fpregs +#define process_write_regs32 netbsd32_process_write_regs +#define process_write_fpregs32 netbsd32_process_write_fpregs + #define process_reg32 struct reg32 #define process_fpreg32 struct fpreg32 #endif /* COMPAT_NETBSD32 */ Index: sys/arch/sparc64/include/netbsd32_machdep.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/include/netbsd32_machdep.h,v retrieving revision 1.28 diff -u -p -r1.28 netbsd32_machdep.h --- sys/arch/sparc64/include/netbsd32_machdep.h 4 Jan 2014 00:10:03 -0000 1.28 +++ sys/arch/sparc64/include/netbsd32_machdep.h 15 Oct 2016 12:40:13 -0000 @@ -79,4 +79,7 @@ int netbsd32_md_ioctl(struct file *, net int netbsd32_process_read_regs(struct lwp *, struct reg32 *); int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); +int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); +int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); + #endif /* _MACHINE_NETBSD32_H_ */ Index: sys/arch/sparc64/include/ptrace.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/include/ptrace.h,v retrieving revision 1.4 diff -u -p -r1.4 ptrace.h --- sys/arch/sparc64/include/ptrace.h 28 Sep 2016 11:44:16 -0000 1.4 +++ sys/arch/sparc64/include/ptrace.h 15 Oct 2016 12:40:13 -0000 @@ -11,6 +11,9 @@ #define process_read_regs32 netbsd32_process_read_regs #define process_read_fpregs32 netbsd32_process_read_fpregs +#define process_write_regs32 netbsd32_process_write_regs +#define process_write_fpregs32 netbsd32_process_write_fpregs + #define process_reg32 struct reg32 #define process_fpreg32 struct fpreg32 #endif Index: sys/arch/sparc64/sparc64/netbsd32_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/netbsd32_machdep.c,v retrieving revision 1.109 diff -u -p -r1.109 netbsd32_machdep.c --- sys/arch/sparc64/sparc64/netbsd32_machdep.c 26 Nov 2015 13:15:34 -0000 1.109 +++ sys/arch/sparc64/sparc64/netbsd32_machdep.c 15 Oct 2016 12:40:14 -0000 @@ -624,16 +624,15 @@ netbsd32_process_read_regs(struct lwp *l return (0); } -#if 0 int netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) { - struct trapframe64* tf = p->p_md.md_tf; + struct trapframe64* tf = l->l_md.md_tf; int i; tf->tf_pc = regs->r_pc; tf->tf_npc = regs->r_npc; - tf->tf_y = regs->r_pc; + tf->tf_y = regs->r_y; for (i = 0; i < 8; i++) { tf->tf_global[i] = regs->r_global[i]; tf->tf_out[i] = regs->r_out[i]; @@ -643,7 +642,6 @@ netbsd32_process_write_regs(struct lwp * PSRCC_TO_TSTATE(regs->r_psr); return (0); } -#endif int netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz) @@ -661,9 +659,9 @@ netbsd32_process_read_fpregs(struct lwp return 0; } -#if 0 int -netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs) +netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs, + size_t sz) { struct fpstate64 *statep; int i; @@ -678,7 +676,6 @@ netbsd32_process_write_fpregs(struct lwp return 0; } -#endif /* * 32-bit version of cpu_coredump. Index: sys/compat/netbsd32/files.netbsd32 =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/files.netbsd32,v retrieving revision 1.38 diff -u -p -r1.38 files.netbsd32 --- sys/compat/netbsd32/files.netbsd32 3 Dec 2015 11:25:45 -0000 1.38 +++ sys/compat/netbsd32/files.netbsd32 15 Oct 2016 12:40:14 -0000 @@ -21,6 +21,7 @@ file compat/netbsd32/netbsd32_module.c c file compat/netbsd32/netbsd32_mod.c compat_netbsd32 file compat/netbsd32/netbsd32_mqueue.c compat_netbsd32 & mqueue file compat/netbsd32/netbsd32_nfssvc.c compat_netbsd32 & nfsserver +file compat/netbsd32/netbsd32_ptrace.c compat_netbsd32 & ptrace file compat/netbsd32/netbsd32_select.c compat_netbsd32 file compat/netbsd32/netbsd32_sem.c compat_netbsd32 file compat/netbsd32/netbsd32_signal.c compat_netbsd32 Index: sys/compat/netbsd32/netbsd32.h =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32.h,v retrieving revision 1.112 diff -u -p -r1.112 netbsd32.h --- sys/compat/netbsd32/netbsd32.h 23 Sep 2016 14:16:32 -0000 1.112 +++ sys/compat/netbsd32/netbsd32.h 15 Oct 2016 12:40:17 -0000 @@ -282,6 +282,16 @@ struct netbsd32_export_args30 { /* from */ typedef netbsd32_pointer_t netbsd32_pollfdp_t; +/* from */ +typedef netbsd32_pointer_t netbsd32_ptrace_io_descp_t; +struct netbsd32_ptrace_io_desc { + int piod_op; /* I/O operation */ + netbsd32_voidp piod_offs; /* child offset */ + netbsd32_voidp piod_addr; /* parent offset */ + netbsd32_size_t piod_len; /* request length (in) / + actual count (out) */ +}; + /* from */ typedef netbsd32_pointer_t netbsd32_quotactlargsp_t; struct netbsd32_quotactlargs { Index: sys/compat/netbsd32/netbsd32_netbsd.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v retrieving revision 1.204 diff -u -p -r1.204 netbsd32_netbsd.c --- sys/compat/netbsd32/netbsd32_netbsd.c 17 Sep 2016 02:44:38 -0000 1.204 +++ sys/compat/netbsd32/netbsd32_netbsd.c 15 Oct 2016 12:40:17 -0000 @@ -406,25 +406,6 @@ netbsd32_setuid(struct lwp *l, const str } int -netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, register_t *retval) -{ - /* { - syscallarg(int) req; - syscallarg(pid_t) pid; - syscallarg(netbsd32_voidp) addr; - syscallarg(int) data; - } */ - struct sys_ptrace_args ua; - - NETBSD32TO64_UAP(req); - NETBSD32TO64_UAP(pid); - NETBSD32TOP_UAP(addr, void *); - NETBSD32TO64_UAP(data); - - return (*sysent[SYS_ptrace].sy_call)(l, &ua, retval); -} - -int netbsd32_accept(struct lwp *l, const struct netbsd32_accept_args *uap, register_t *retval) { /* { Index: sys/compat/netbsd32/netbsd32_ptrace.c =================================================================== RCS file: sys/compat/netbsd32/netbsd32_ptrace.c diff -N sys/compat/netbsd32/netbsd32_ptrace.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/compat/netbsd32/netbsd32_ptrace.c 15 Oct 2016 12:40:17 -0000 @@ -0,0 +1,217 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#if defined(_KERNEL_OPT) +#include "opt_ptrace.h" +#include "opt_compat_netbsd.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +extern struct emul emul_netbsd32; + + +/* + * PTRACE methods + */ + +static int netbsd32_copyinpiod(struct ptrace_io_desc *, const void *); +static void netbsd32_copyoutpiod(const struct ptrace_io_desc *, void *); +static int netbsd32_doregs(struct lwp *, struct lwp *, struct uio *); +static int netbsd32_dofpregs(struct lwp *, struct lwp *, struct uio *); + + +static int +netbsd32_copyinpiod(struct ptrace_io_desc *piod, const void *addr) +{ + struct netbsd32_ptrace_io_desc piod32; + + int error = copyin(addr, &piod32, sizeof(piod32)); + if (error) + return error; + piod->piod_op = piod32.piod_op; + piod->piod_offs = NETBSD32PTR64(piod32.piod_offs); + piod->piod_addr = NETBSD32PTR64(piod32.piod_addr); + piod->piod_len = (size_t)piod32.piod_len; + + return 0; +} + +static void +netbsd32_copyoutpiod(const struct ptrace_io_desc *piod, void *addr) +{ + struct netbsd32_ptrace_io_desc piod32; + + piod32.piod_op = piod->piod_op; + NETBSD32PTR32(piod32.piod_offs, piod->piod_offs); + NETBSD32PTR32(piod32.piod_addr, piod->piod_addr); + piod32.piod_len = (netbsd32_size_t)piod->piod_len; + (void) copyout(&piod32, addr, sizeof(piod32)); +} + + +static int +netbsd32_doregs(struct lwp *curl /*tracer*/, + struct lwp *l /*traced*/, + struct uio *uio) +{ +#if defined(PT_GETREGS) || defined(PT_SETREGS) + process_reg32 r32; + int error; + char *kv; + int kl; + + if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) + return EINVAL; + + kl = sizeof(r32); + kv = (char *)&r32; + + kv += uio->uio_offset; + kl -= uio->uio_offset; + if ((size_t)kl > uio->uio_resid) + kl = uio->uio_resid; + error = process_read_regs32(l, &r32); + if (error == 0) + error = uiomove(kv, kl, uio); + if (error == 0 && uio->uio_rw == UIO_WRITE) { + if (l->l_stat != LSSTOP) + error = EBUSY; + else + error = process_write_regs32(l, &r32); + } + + uio->uio_offset = 0; + return error; +#else + return EINVAL; +#endif +} + +static int +netbsd32_dofpregs(struct lwp *curl /*tracer*/, + struct lwp *l /*traced*/, + struct uio *uio) +{ +#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) + process_fpreg32 r32; + int error; + char *kv; + size_t kl; + + KASSERT(l->l_proc->p_flag & PK_32); + if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) + return EINVAL; + kl = sizeof(r32); + kv = (char *)&r32; + + kv += uio->uio_offset; + kl -= uio->uio_offset; + if (kl > uio->uio_resid) + kl = uio->uio_resid; + + error = process_read_fpregs32(l, &r32, &kl); + if (error == 0) + error = uiomove(kv, kl, uio); + if (error == 0 && uio->uio_rw == UIO_WRITE) { + if (l->l_stat != LSSTOP) + error = EBUSY; + else + error = process_write_fpregs32(l, &r32, kl); + } + uio->uio_offset = 0; + return error; +#else + return EINVAL; +#endif +} + +static struct ptrace_methods netbsd32_ptm = { + .ptm_copyinpiod = netbsd32_copyinpiod, + .ptm_copyoutpiod = netbsd32_copyoutpiod, + .ptm_doregs = netbsd32_doregs, + .ptm_dofpregs = netbsd32_dofpregs +}; + + +int +netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, + register_t *retval) +{ + /* { + syscallarg(int) req; + syscallarg(pid_t) pid; + syscallarg(netbsd32_voidp *) addr; + syscallarg(int) data; + } */ + + return do_ptrace(&netbsd32_ptm, l, SCARG(uap, req), SCARG(uap, pid), + SCARG_P32(uap, addr), SCARG(uap, data), retval); +} + +static const struct syscall_package compat_ptrace_syscalls[] = { + { NETBSD32_SYS_netbsd32_ptrace, 0, (sy_call_t *)netbsd32_ptrace }, + { 0, 0, NULL }, +}; + +MODULE(MODULE_CLASS_EXEC, compat_netbsd32_ptrace, "compat_netbsd32"); + +static int +compat_netbsd32_ptrace_modcmd(modcmd_t cmd, void *arg) +{ + int error; + + switch (cmd) { + case MODULE_CMD_INIT: + error = syscall_establish(&emul_netbsd32, + compat_ptrace_syscalls); + break; + case MODULE_CMD_FINI: + error = syscall_disestablish(&emul_netbsd32, + compat_ptrace_syscalls); + break; + default: + error = ENOTTY; + break; + } + return error; +} Index: sys/compat/netbsd32/netbsd32_syscalls_autoload.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_syscalls_autoload.c,v retrieving revision 1.6 diff -u -p -r1.6 netbsd32_syscalls_autoload.c --- sys/compat/netbsd32/netbsd32_syscalls_autoload.c 23 Sep 2016 14:12:25 -0000 1.6 +++ sys/compat/netbsd32/netbsd32_syscalls_autoload.c 15 Oct 2016 12:40:18 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_syscalls_autoload.c,v 1.6 2016/09/23 14:12:25 skrll Exp $ */ +/* $NetBSD$ */ /* * System call autoload table. @@ -8,10 +8,11 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_syscalls_autoload.c,v 1.6 2016/09/23 14:12:25 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include static struct sc_autoload netbsd32_syscalls_autoload[] = { + { NETBSD32_SYS_netbsd32_ptrace, "compat_netbsd32_ptrace" }, { NETBSD32_SYS_netbsd32_nfssvc, "compat_netbsd32_nfssrv" }, { NETBSD32_SYS_compat_10_osemsys, "compat_netbsd32_sysvipc" }, { NETBSD32_SYS_compat_10_omsgsys, "compat_netbsd32_sysvipc" }, Index: sys/compat/netbsd32/netbsd32_sysent.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_sysent.c,v retrieving revision 1.123 diff -u -p -r1.123 netbsd32_sysent.c --- sys/compat/netbsd32/netbsd32_sysent.c 23 Sep 2016 14:12:25 -0000 1.123 +++ sys/compat/netbsd32/netbsd32_sysent.c 15 Oct 2016 12:40:18 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_sysent.c,v 1.123 2016/09/23 14:12:25 skrll Exp $ */ +/* $NetBSD$ */ /* * System call switch table. @@ -8,7 +8,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_sysent.c,v 1.123 2016/09/23 14:12:25 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -220,7 +220,7 @@ struct sysent netbsd32_sysent[] = { }, /* 25 = geteuid */ { ns(struct netbsd32_ptrace_args), - .sy_call = (sy_call_t *)netbsd32_ptrace + .sy_call = (sy_call_t *)sys_nomodule }, /* 26 = netbsd32_ptrace */ { ns(struct netbsd32_recvmsg_args), Index: sys/compat/netbsd32/netbsd32_systrace_args.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_systrace_args.c,v retrieving revision 1.14 diff -u -p -r1.14 netbsd32_systrace_args.c --- sys/compat/netbsd32/netbsd32_systrace_args.c 23 Sep 2016 14:12:25 -0000 1.14 +++ sys/compat/netbsd32/netbsd32_systrace_args.c 15 Oct 2016 12:40:21 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_systrace_args.c,v 1.14 2016/09/23 14:12:25 skrll Exp $ */ +/* $NetBSD$ */ /* * System call argument to DTrace register array converstion. Index: sys/compat/netbsd32/syscalls.master =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/syscalls.master,v retrieving revision 1.114 diff -u -p -r1.114 syscalls.master --- sys/compat/netbsd32/syscalls.master 23 Sep 2016 14:10:28 -0000 1.114 +++ sys/compat/netbsd32/syscalls.master 15 Oct 2016 12:40:21 -0000 @@ -99,7 +99,8 @@ 23 STD { int|netbsd32||setuid(uid_t uid); } 24 NOARGS { uid_t|sys||getuid(void); } 25 NOARGS { uid_t|sys||geteuid(void); } -26 STD { int|netbsd32||ptrace(int req, pid_t pid, \ +26 STD MODULAR compat_netbsd32_ptrace \ + { int|netbsd32||ptrace(int req, pid_t pid, \ netbsd32_voidp addr, int data); } 27 STD { netbsd32_ssize_t|netbsd32||recvmsg(int s, \ netbsd32_msghdrp_t msg, int flags); } Index: sys/kern/sys_process.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_process.c,v retrieving revision 1.173 diff -u -p -r1.173 sys_process.c --- sys/kern/sys_process.c 15 Oct 2016 09:09:55 -0000 1.173 +++ sys/kern/sys_process.c 15 Oct 2016 12:40:21 -0000 @@ -120,9 +120,11 @@ #include __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.173 2016/10/15 09:09:55 skrll Exp $"); +#ifdef _KERNEL_OPT #include "opt_ptrace.h" #include "opt_ktrace.h" #include "opt_pax.h" +#endif #include #include @@ -231,6 +233,26 @@ ptrace_init(void) ptrace_listener_cb, NULL); } +static int +ptrace_copyinpiod(struct ptrace_io_desc *piod, const void *addr) +{ + return copyin(addr, piod, sizeof(*piod)); +} + +static void +ptrace_copyoutpiod(const struct ptrace_io_desc *piod, void *addr) +{ + (void) copyout(piod, addr, sizeof(*piod)); +} + + +static struct ptrace_methods native_ptm = { + .ptm_copyinpiod = ptrace_copyinpiod, + .ptm_copyoutpiod = ptrace_copyoutpiod, + .ptm_doregs = process_doregs, + .ptm_dofpregs = process_dofpregs, +}; + /* * Process debugging system call. */ @@ -243,6 +265,15 @@ sys_ptrace(struct lwp *l, const struct s syscallarg(void *) addr; syscallarg(int) data; } */ + + return do_ptrace(&native_ptm, l, SCARG(uap, req), SCARG(uap, pid), + SCARG(uap, addr), SCARG(uap, data), retval); +} + +int +do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid, + void *addr, int data, register_t *retval) +{ struct proc *p = l->l_proc; struct lwp *lt; #ifdef PT_STEP @@ -256,15 +287,13 @@ sys_ptrace(struct lwp *l, const struct s struct ptrace_state ps; struct ptrace_lwpinfo pl; struct vmspace *vm; - int error, write, tmp, req, pheld; + int error, write, tmp, pheld; int signo = 0; int resume_all; ksiginfo_t ksi; char *path; int len = 0; - error = 0; - req = SCARG(uap, req); /* * If attaching or detaching, we need to get a write hold on the @@ -278,7 +307,7 @@ sys_ptrace(struct lwp *l, const struct s mutex_enter(t->p_lock); } else { /* Find the process we're supposed to be operating on. */ - t = proc_find(SCARG(uap, pid)); + t = proc_find(pid); if (t == NULL) { mutex_exit(proc_lock); return ESRCH; @@ -507,13 +536,13 @@ sys_ptrace(struct lwp *l, const struct s /* * Can't write to a RAS */ - if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { + if (ras_lookup(t, addr) != (void *)-1) { error = EACCES; break; } #endif write = 1; - tmp = SCARG(uap, data); + tmp = data; /* FALLTHROUGH */ case PT_READ_I: /* XXX no separate I and D spaces */ @@ -523,7 +552,7 @@ sys_ptrace(struct lwp *l, const struct s iov.iov_len = sizeof(tmp); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr); + uio.uio_offset = (off_t)(unsigned long)addr; uio.uio_resid = sizeof(tmp); uio.uio_rw = write ? UIO_WRITE : UIO_READ; UIO_SETUP_SYSSPACE(&uio); @@ -534,7 +563,7 @@ sys_ptrace(struct lwp *l, const struct s break; case PT_IO: - error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); + error = ptm->ptm_copyinpiod(&piod, addr); if (error) break; @@ -555,7 +584,7 @@ sys_ptrace(struct lwp *l, const struct s /* * Can't write to a RAS */ - if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { + if (ras_lookup(t, addr) != (void *)-1) { return EACCES; } uio.uio_rw = UIO_WRITE; @@ -586,14 +615,15 @@ sys_ptrace(struct lwp *l, const struct s error = process_domem(l, lt, &uio); piod.piod_len -= uio.uio_resid; - (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); + (void) ptm->ptm_copyoutpiod(&piod, addr); + uvmspace_free(vm); break; case PT_DUMPCORE: - if ((path = SCARG(uap, addr)) != NULL) { + if ((path = addr) != NULL) { char *dst; - len = SCARG(uap, data); + len = data; if (len < 0 || len >= MAXPATHLEN) { error = EINVAL; @@ -648,7 +678,7 @@ sys_ptrace(struct lwp *l, const struct s * For operations other than PT_STEP, data > 0 means * data is the signo to deliver to the process. */ - tmp = SCARG(uap, data); + tmp = data; if (tmp >= 0) { #ifdef PT_STEP if (req == PT_STEP) @@ -697,8 +727,8 @@ sys_ptrace(struct lwp *l, const struct s } /* If the address parameter is not (int *)1, set the pc. */ - if ((int *)SCARG(uap, addr) != (int *)1) { - error = process_set_pc(lt, SCARG(uap, addr)); + if ((int *)addr != (int *)1) { + error = process_set_pc(lt, addr); if (error != 0) break; } @@ -797,26 +827,26 @@ sys_ptrace(struct lwp *l, const struct s goto sendsig; case PT_GET_EVENT_MASK: - if (SCARG(uap, data) != sizeof(pe)) { + if (data != sizeof(pe)) { DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pe))); + data, sizeof(pe))); error = EINVAL; break; } memset(&pe, 0, sizeof(pe)); pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? PTRACE_FORK : 0; - error = copyout(&pe, SCARG(uap, addr), sizeof(pe)); + error = copyout(&pe, addr, sizeof(pe)); break; case PT_SET_EVENT_MASK: - if (SCARG(uap, data) != sizeof(pe)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pe))); + if (data != sizeof(pe)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(pe))); error = EINVAL; break; } - if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))) != 0) + if ((error = copyin(addr, &pe, sizeof(pe))) != 0) return error; if (pe.pe_set_event & PTRACE_FORK) SET(t->p_slflag, PSL_TRACEFORK); @@ -825,9 +855,9 @@ sys_ptrace(struct lwp *l, const struct s break; case PT_GET_PROCESS_STATE: - if (SCARG(uap, data) != sizeof(ps)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(ps))); + if (data != sizeof(ps)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(ps))); error = EINVAL; break; } @@ -836,17 +866,17 @@ sys_ptrace(struct lwp *l, const struct s ps.pe_report_event = PTRACE_FORK; ps.pe_other_pid = t->p_fpid; } - error = copyout(&ps, SCARG(uap, addr), sizeof(ps)); + error = copyout(&ps, addr, sizeof(ps)); break; case PT_LWPINFO: - if (SCARG(uap, data) != sizeof(pl)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pl))); + if (data != sizeof(pl)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(pl))); error = EINVAL; break; } - error = copyin(SCARG(uap, addr), &pl, sizeof(pl)); + error = copyin(addr, &pl, sizeof(pl)); if (error) break; tmp = pl.pl_lwpid; @@ -875,7 +905,7 @@ sys_ptrace(struct lwp *l, const struct s } mutex_exit(t->p_lock); - error = copyout(&pl, SCARG(uap, addr), sizeof(pl)); + error = copyout(&pl, addr, sizeof(pl)); break; #ifdef PT_SETREGS @@ -887,7 +917,7 @@ sys_ptrace(struct lwp *l, const struct s /* write = 0 done above. */ #endif #if defined(PT_SETREGS) || defined(PT_GETREGS) - tmp = SCARG(uap, data); + tmp = data; if (tmp != 0 && t->p_nlwps > 1) { lwp_delref(lt); mutex_enter(t->p_lock); @@ -903,19 +933,19 @@ sys_ptrace(struct lwp *l, const struct s if (!process_validregs(lt)) error = EINVAL; else { - error = proc_vmspace_getref(l->l_proc, &vm); + error = proc_vmspace_getref(p, &vm); if (error) break; - iov.iov_base = SCARG(uap, addr); - iov.iov_len = sizeof(struct reg); + iov.iov_base = addr; + iov.iov_len = PROC_REGSZ(p); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; - uio.uio_resid = sizeof(struct reg); + uio.uio_resid = iov.iov_len; uio.uio_rw = write ? UIO_WRITE : UIO_READ; uio.uio_vmspace = vm; - error = process_doregs(l, lt, &uio); + error = ptm->ptm_doregs(l, lt, &uio); uvmspace_free(vm); } break; @@ -930,7 +960,7 @@ sys_ptrace(struct lwp *l, const struct s /* write = 0 done above. */ #endif #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) - tmp = SCARG(uap, data); + tmp = data; if (tmp != 0 && t->p_nlwps > 1) { lwp_delref(lt); mutex_enter(t->p_lock); @@ -946,19 +976,19 @@ sys_ptrace(struct lwp *l, const struct s if (!process_validfpregs(lt)) error = EINVAL; else { - error = proc_vmspace_getref(l->l_proc, &vm); + error = proc_vmspace_getref(p, &vm); if (error) break; - iov.iov_base = SCARG(uap, addr); - iov.iov_len = sizeof(struct fpreg); + iov.iov_base = addr; + iov.iov_len = PROC_FPREGSZ(p); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; - uio.uio_resid = sizeof(struct fpreg); + uio.uio_resid = iov.iov_len; uio.uio_rw = write ? UIO_WRITE : UIO_READ; uio.uio_vmspace = vm; - error = process_dofpregs(l, lt, &uio); + error = ptm->ptm_dofpregs(l, lt, &uio); uvmspace_free(vm); } break; @@ -966,8 +996,7 @@ sys_ptrace(struct lwp *l, const struct s #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES - error = ptrace_machdep_dorequest(l, lt, - req, SCARG(uap, addr), SCARG(uap, data)); + error = ptrace_machdep_dorequest(l, lt, req, addr, data); break; #endif } Index: sys/modules/Makefile =================================================================== RCS file: /cvsroot/src/sys/modules/Makefile,v retrieving revision 1.180 diff -u -p -r1.180 Makefile --- sys/modules/Makefile 15 Oct 2016 12:38:03 -0000 1.180 +++ sys/modules/Makefile 15 Oct 2016 12:40:21 -0000 @@ -236,6 +236,7 @@ SUBDIR+= wmimsi SUBDIR+= compat_netbsd32 SUBDIR+= compat_netbsd32_mqueue SUBDIR+= compat_netbsd32_nfssrv +SUBDIR+= compat_netbsd32_ptrace SUBDIR+= compat_netbsd32_sysvipc .endif @@ -244,6 +245,7 @@ SUBDIR+= compat_linux32 SUBDIR+= compat_netbsd32 SUBDIR+= compat_netbsd32_mqueue SUBDIR+= compat_netbsd32_nfssrv +SUBDIR+= compat_netbsd32_ptrace SUBDIR+= compat_netbsd32_sysvipc .endif Index: sys/sys/proc.h =================================================================== RCS file: /cvsroot/src/sys/sys/proc.h,v retrieving revision 1.334 diff -u -p -r1.334 proc.h --- sys/sys/proc.h 29 Sep 2016 20:40:53 -0000 1.334 +++ sys/sys/proc.h 15 Oct 2016 12:40:22 -0000 @@ -557,6 +557,10 @@ _proclist_skipmarker(struct proc *p0) } #define PROC_PTRSZ(p) (((p)->p_flag & PK_32) ? sizeof(int) : sizeof(void *)) +#define PROC_REGSZ(p) (((p)->p_flag & PK_32) ? \ + sizeof(process_reg32) : sizeof(struct reg)) +#define PROC_FPREGSZ(p) (((p)->p_flag & PK_32) ? \ + sizeof(process_fpreg32) : sizeof(struct fpreg)) /* * PROCLIST_FOREACH: iterate on the given proclist, skipping PK_MARKER ones. Index: sys/sys/ptrace.h =================================================================== RCS file: /cvsroot/src/sys/sys/ptrace.h,v retrieving revision 1.46 diff -u -p -r1.46 ptrace.h --- sys/sys/ptrace.h 2 Jul 2015 03:47:54 -0000 1.46 +++ sys/sys/ptrace.h 15 Oct 2016 12:40:22 -0000 @@ -139,6 +139,13 @@ struct fpreg; #endif #endif +struct ptrace_methods { + int (*ptm_copyinpiod)(struct ptrace_io_desc *, const void *); + void (*ptm_copyoutpiod)(const struct ptrace_io_desc *, void *); + int (*ptm_doregs)(struct lwp *, struct lwp *, struct uio *); + int (*ptm_dofpregs)(struct lwp *, struct lwp *, struct uio *); +}; + void ptrace_init(void); int process_doregs(struct lwp *, struct lwp *, struct uio *); @@ -153,6 +160,10 @@ void process_stoptrace(void); void proc_reparent(struct proc *, struct proc *); + +int do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *, + int, register_t *); + /* * 64bit architectures that support 32bit emulation (amd64 and sparc64) * will #define process_read_regs32 to netbsd32_process_read_regs (etc). @@ -180,9 +191,21 @@ int process_set_pc(struct lwp *, void *) int process_sstep(struct lwp *, int); #ifdef PT_SETFPREGS int process_write_fpregs(struct lwp *, const struct fpreg *, size_t); +#ifndef process_write_fpregs32 +#define process_write_fpregs32 process_write_fpregs +#endif +#ifndef process_write_fpregs64 +#define process_write_fpregs64 process_write_fpregs +#endif #endif #ifdef PT_SETREGS int process_write_regs(struct lwp *, const struct reg *); +#ifndef process_write_regs32 +#define process_write_regs32 process_write_regs +#endif +#ifndef process_write_regs64 +#define process_write_regs64 process_write_regs +#endif #endif #ifdef __HAVE_PROCFS_MACHDEP