Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Relax prohibition of Program Counter set to 0x0 in ...



details:   https://anonhg.NetBSD.org/src/rev/1992334dd7a5
branches:  trunk
changeset: 451475:1992334dd7a5
user:      kamil <kamil%NetBSD.org@localhost>
date:      Sat May 25 03:20:43 2019 +0000

description:
Relax prohibition of Program Counter set to 0x0 in ptrace(2)

In PT_CONTINUE, PT_SYSCALL and PT_DETACH the 3rd argument of ptrace(2)
allows to set PC. It used to be allowed to set PC to 0x0 without
restrictions, later prohibited unconditionally.

Change the condition and make it depending on vm.user_va0_disable. Whenever
the VA 0 mapping is disallowed, reject setting PC to 0x0.

While there comment truncated and empty transfers in PT_READ/PT_WRITE
and PT_IO.

diffstat:

 sys/kern/sys_ptrace_common.c |  47 +++++++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 22 deletions(-)

diffs (91 lines):

diff -r d014e502a93c -r 1992334dd7a5 sys/kern/sys_ptrace_common.c
--- a/sys/kern/sys_ptrace_common.c      Sat May 25 02:49:26 2019 +0000
+++ b/sys/kern/sys_ptrace_common.c      Sat May 25 03:20:43 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_ptrace_common.c,v 1.53 2019/05/10 21:08:26 mgorny Exp $    */
+/*     $NetBSD: sys_ptrace_common.c,v 1.54 2019/05/25 03:20:43 kamil Exp $     */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.53 2019/05/10 21:08:26 mgorny Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.54 2019/05/25 03:20:43 kamil Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -163,6 +163,8 @@
 static kauth_listener_t ptrace_listener;
 static int process_auxv_offset(struct proc *, struct uio *);
 
+extern int user_va0_disable;
+
 #if 0
 static int ptrace_cbref;
 static kmutex_t ptrace_mtx;
@@ -1106,12 +1108,15 @@
                piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
                if ((error = ptrace_doio(l, t, lt, &piod, addr, true)) != 0)
                        break;
-#if 0 // XXX: GDB depends on it
-               if (piod.piod_len < sizeof(tmp)) {
-                       error = EIO;
-                       break;
-               }
-#endif
+               /*
+                * For legacy reasons we treat here two results as success:
+                *  - incomplete transfer  piod.piod_len < sizeof(tmp)
+                *  - no transfer          piod.piod_len == 0
+                *
+                * This means that there is no way to determine whether
+                * transfer operation was performed in PT_WRITE and PT_READ
+                * calls.
+                */
                if (!write)
                        *retval = tmp;
                break;
@@ -1125,12 +1130,11 @@
                }
                if ((error = ptrace_doio(l, t, lt, &piod, addr, false)) != 0)
                        break;
-#if 0 // XXX: GDB depends on it
-               if (piod.piod_len < 1) {
-                       error = EIO;
-                       break;
-               }
-#endif
+               /*
+                * For legacy reasons we treat here two results as success:
+                *  - incomplete transfer  piod.piod_len < sizeof(tmp)
+                *  - no transfer          piod.piod_len == 0
+                */
                error = ptm->ptm_copyout_piod(&piod, addr, data);
                break;
 
@@ -1251,16 +1255,15 @@
                }
 
                /*
-                * If the address parameter is 0, report error.
+                * Reject setting program cunter to 0x0 if VA0 is disabled.
                 *
-                * It's a popular mistake to set Program Counter to 0x0.
-                * In certain kernels this is allowable parameter and causes
-                * portability issue.
-                *
-                * Disallow explicitly zeroed PC, instead of triggering
-                * a harder to debug crash later.
+                * Not all kernels implement this feature to set Program
+                * Counter in one go in PT_CONTINUE and similar operations.
+                * This causes portability issues as passing address 0x0
+                * on these kernels is no-operation, but can cause failure
+                * in most cases on NetBSD.
                 */
-               if (addr == 0) {
+               if (user_va0_disable && addr == 0) {
                        error = EINVAL;
                        break;
                }



Home | Main Index | Thread Index | Old Index