diff options
| author | mgorny <mgorny@NetBSD.org> | 2019-06-04 16:29:53 +0000 |
|---|---|---|
| committer | mgorny <mgorny@NetBSD.org> | 2019-06-04 16:29:53 +0000 |
| commit | b98b74f8a435c19d49380c0673eb6523bad10617 (patch) | |
| tree | cbfb4afe15acad70b638f0584f1dcadaa93a3fb1 | |
| parent | 47857fd4cf4779bb36c06adc47137232fce37791 (diff) | |
compat32: Translate userland PT_* request values into kernel codes
Currently, the compat32 passes PT_* request values to kernel functions
without translation. This works fine for low PT_* requests that happen
to have the same values both on i386 and amd64. However, for requests
higher than PT_SETFPREGS, the value passed from userland (matching i386
const) does not match the correct kernel (amd64) request. As a result,
e.g. when compat32 process calls PT_GETDBREGS, kernel actually processes
it as PT_SETSTEP.
To resolve this, introduce support for compat32 PT_* request
translation. The interface is based on PTRACE_TRANSLATE_REQUEST32 macro
that is defined to a mapping function on architectures needing it.
In case of amd64, this function maps userland i386 PT_* values into
appropriate amd64 PT_* values.
For the time being, the two additional PT_GETXMMREGS and PT_SETXMMREGS
requests are unsupported due to lack of matching free amd64 constant.
| -rw-r--r-- | sys/arch/amd64/amd64/netbsd32_machdep.c | 26 | ||||
| -rw-r--r-- | sys/arch/amd64/include/netbsd32_machdep.h | 21 | ||||
| -rw-r--r-- | sys/arch/amd64/include/ptrace.h | 4 | ||||
| -rw-r--r-- | sys/compat/netbsd32/netbsd32_ptrace.c | 16 |
4 files changed, 60 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/netbsd32_machdep.c b/sys/arch/amd64/amd64/netbsd32_machdep.c index 39d671a4b9b..6d71b176cbf 100644 --- a/sys/arch/amd64/amd64/netbsd32_machdep.c +++ b/sys/arch/amd64/amd64/netbsd32_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.121 2019/05/19 08:46:15 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.122 2019/06/04 16:29:53 mgorny Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.121 2019/05/19 08:46:15 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.122 2019/06/04 16:29:53 mgorny Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -336,6 +336,28 @@ cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie, #endif int +netbsd32_ptrace_translate_request(int req) +{ + + switch (req) + { + case 0 ... PT_FIRSTMACH - 1: return req; + case PT32_STEP: return PT_STEP; + case PT32_GETREGS: return PT_GETREGS; + case PT32_SETREGS: return PT_SETREGS; + case PT32_GETFPREGS: return PT_GETFPREGS; + case PT32_SETFPREGS: return PT_SETFPREGS; + case PT32_GETXMMREGS: return -1; + case PT32_SETXMMREGS: return -1; + case PT32_GETDBREGS: return PT_GETDBREGS; + case PT32_SETDBREGS: return PT_SETDBREGS; + case PT32_SETSTEP: return PT_SETSTEP; + case PT32_CLEARSTEP: return PT_CLEARSTEP; + default: return -1; + } +} + +int netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs) { struct trapframe *tf = l->l_md.md_regs; diff --git a/sys/arch/amd64/include/netbsd32_machdep.h b/sys/arch/amd64/include/netbsd32_machdep.h index 51691eb7c90..e7f018708c2 100644 --- a/sys/arch/amd64/include/netbsd32_machdep.h +++ b/sys/arch/amd64/include/netbsd32_machdep.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.h,v 1.22 2017/02/23 03:34:22 kamil Exp $ */ +/* $NetBSD: netbsd32_machdep.h,v 1.23 2019/06/04 16:29:53 mgorny Exp $ */ #ifndef _MACHINE_NETBSD32_H_ #define _MACHINE_NETBSD32_H_ @@ -7,6 +7,22 @@ #include <compat/sys/ucontext.h> #include <compat/sys/siginfo.h> +/* + * i386 ptrace constants + * Please keep in sync with sys/arch/i386/include/ptrace.h. + */ +#define PT32_STEP (PT_FIRSTMACH + 0) +#define PT32_GETREGS (PT_FIRSTMACH + 1) +#define PT32_SETREGS (PT_FIRSTMACH + 2) +#define PT32_GETFPREGS (PT_FIRSTMACH + 3) +#define PT32_SETFPREGS (PT_FIRSTMACH + 4) +#define PT32_GETXMMREGS (PT_FIRSTMACH + 5) +#define PT32_SETXMMREGS (PT_FIRSTMACH + 6) +#define PT32_GETDBREGS (PT_FIRSTMACH + 7) +#define PT32_SETDBREGS (PT_FIRSTMACH + 8) +#define PT32_SETSTEP (PT_FIRSTMACH + 9) +#define PT32_CLEARSTEP (PT_FIRSTMACH + 10) + #define NETBSD32_POINTER_TYPE uint32_t typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t; @@ -151,6 +167,9 @@ struct x86_64_set_mtrr_args32 { #define NETBSD32_MID_MACHINE MID_I386 +/* Translate ptrace() PT_* request from 32-bit userland to kernel. */ +int netbsd32_ptrace_translate_request(int); + int netbsd32_process_read_regs(struct lwp *, struct reg32 *); int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); int netbsd32_process_read_dbregs(struct lwp *, struct dbreg32 *, size_t *); diff --git a/sys/arch/amd64/include/ptrace.h b/sys/arch/amd64/include/ptrace.h index c5cef941fd1..799f32ec775 100644 --- a/sys/arch/amd64/include/ptrace.h +++ b/sys/arch/amd64/include/ptrace.h @@ -1,4 +1,4 @@ -/* $NetBSD: ptrace.h,v 1.13 2019/02/07 00:19:54 kamil Exp $ */ +/* $NetBSD: ptrace.h,v 1.14 2019/06/04 16:29:53 mgorny Exp $ */ /* * Copyright (c) 1993 Christopher G. Demetriou @@ -87,6 +87,8 @@ #define process_reg32 struct reg32 #define process_fpreg32 struct fpreg32 #define process_dbreg32 struct dbreg32 + +#define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x) #endif /* COMPAT_NETBSD32 */ #endif /* _KERNEL_OPT */ diff --git a/sys/compat/netbsd32/netbsd32_ptrace.c b/sys/compat/netbsd32/netbsd32_ptrace.c index 614d363c312..1741b852051 100644 --- a/sys/compat/netbsd32/netbsd32_ptrace.c +++ b/sys/compat/netbsd32/netbsd32_ptrace.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_ptrace.c,v 1.6 2019/01/27 02:08:40 pgoyette Exp $ */ +/* $NetBSD: netbsd32_ptrace.c,v 1.7 2019/06/04 16:29:53 mgorny Exp $ */ /* * Copyright (c) 2016 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_ptrace.c,v 1.6 2019/01/27 02:08:40 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_ptrace.c,v 1.7 2019/06/04 16:29:53 mgorny Exp $"); #if defined(_KERNEL_OPT) #include "opt_ptrace.h" @@ -47,6 +47,10 @@ __KERNEL_RCSID(0, "$NetBSD: netbsd32_ptrace.c,v 1.6 2019/01/27 02:08:40 pgoyette #include <compat/netbsd32/netbsd32_syscallargs.h> #include <compat/netbsd32/netbsd32_conv.h> +#ifndef PTRACE_TRANSLATE_REQUEST32 +#define PTRACE_TRANSLATE_REQUEST32(x) x +#endif + /* * PTRACE methods */ @@ -243,6 +247,8 @@ int netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, register_t *retval) { + int req; + /* { syscallarg(int) req; syscallarg(pid_t) pid; @@ -250,7 +256,11 @@ netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, syscallarg(int) data; } */ - return do_ptrace(&netbsd32_ptm, l, SCARG(uap, req), SCARG(uap, pid), + req = PTRACE_TRANSLATE_REQUEST32(SCARG(uap, req)); + if (req == -1) + return EOPNOTSUPP; + + return do_ptrace(&netbsd32_ptm, l, req, SCARG(uap, pid), SCARG_P32(uap, addr), SCARG(uap, data), retval); } |
