Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys compat32: Translate userland PT_* request values into ke...



details:   https://anonhg.NetBSD.org/src/rev/0524ca42793d
branches:  trunk
changeset: 451792:0524ca42793d
user:      mgorny <mgorny%NetBSD.org@localhost>
date:      Tue Jun 04 16:29:53 2019 +0000

description:
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.

diffstat:

 sys/arch/amd64/amd64/netbsd32_machdep.c   |  26 ++++++++++++++++++++++++--
 sys/arch/amd64/include/netbsd32_machdep.h |  21 ++++++++++++++++++++-
 sys/arch/amd64/include/ptrace.h           |   4 +++-
 sys/compat/netbsd32/netbsd32_ptrace.c     |  16 +++++++++++++---
 4 files changed, 60 insertions(+), 7 deletions(-)

diffs (158 lines):

diff -r 0c3a5bbbfa7b -r 0524ca42793d sys/arch/amd64/amd64/netbsd32_machdep.c
--- a/sys/arch/amd64/amd64/netbsd32_machdep.c   Tue Jun 04 15:07:55 2019 +0000
+++ b/sys/arch/amd64/amd64/netbsd32_machdep.c   Tue Jun 04 16:29:53 2019 +0000
@@ -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 @@
 #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 -r 0c3a5bbbfa7b -r 0524ca42793d sys/arch/amd64/include/netbsd32_machdep.h
--- a/sys/arch/amd64/include/netbsd32_machdep.h Tue Jun 04 15:07:55 2019 +0000
+++ b/sys/arch/amd64/include/netbsd32_machdep.h Tue Jun 04 16:29:53 2019 +0000
@@ -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 @@
 
 #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 -r 0c3a5bbbfa7b -r 0524ca42793d sys/arch/amd64/include/ptrace.h
--- a/sys/arch/amd64/include/ptrace.h   Tue Jun 04 15:07:55 2019 +0000
+++ b/sys/arch/amd64/include/ptrace.h   Tue Jun 04 16:29:53 2019 +0000
@@ -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 -r 0c3a5bbbfa7b -r 0524ca42793d sys/compat/netbsd32/netbsd32_ptrace.c
--- a/sys/compat/netbsd32/netbsd32_ptrace.c     Tue Jun 04 15:07:55 2019 +0000
+++ b/sys/compat/netbsd32/netbsd32_ptrace.c     Tue Jun 04 16:29:53 2019 +0000
@@ -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 @@
 #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 @@
 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 @@
                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);
 }
 



Home | Main Index | Thread Index | Old Index