Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Separate flag for suspended by _lwp_suspend and sus...



details:   https://anonhg.NetBSD.org/src/rev/89c69c642deb
branches:  trunk
changeset: 454983:89c69c642deb
user:      kamil <kamil%NetBSD.org@localhost>
date:      Thu Oct 03 22:48:44 2019 +0000

description:
Separate flag for suspended by _lwp_suspend and suspended by a debugger

Once a thread was stopped with ptrace(2), userland process must not
be able to unstop it deliberately or by an accident.

This was a Windows-style behavior that makes threading tracing fragile.

diffstat:

 sys/kern/kern_exit.c         |   5 +++--
 sys/kern/kern_lwp.c          |  13 ++++++++++---
 sys/kern/kern_sig.c          |  20 +++++++++++++++-----
 sys/kern/kern_synch.c        |   5 +++--
 sys/kern/sys_ptrace_common.c |  22 ++++++++++++++--------
 5 files changed, 45 insertions(+), 20 deletions(-)

diffs (223 lines):

diff -r 6a187da7e2ad -r 89c69c642deb sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c      Thu Oct 03 22:29:17 2019 +0000
+++ b/sys/kern/kern_exit.c      Thu Oct 03 22:48:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exit.c,v 1.276 2019/06/13 20:20:18 kamil Exp $    */
+/*     $NetBSD: kern_exit.c,v 1.277 2019/10/03 22:48:44 kamil Exp $    */
 
 /*-
  * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.276 2019/06/13 20:20:18 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.277 2019/10/03 22:48:44 kamil Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_dtrace.h"
@@ -617,6 +617,7 @@
                l2->l_flag |= LW_WEXIT;
                if ((l2->l_stat == LSSLEEP && (l2->l_flag & LW_SINTR)) ||
                    l2->l_stat == LSSUSPENDED || l2->l_stat == LSSTOP) {
+                       l2->l_flag &= ~LW_DBGSUSPEND;
                        /* setrunnable() will release the lock. */
                        setrunnable(l2);
                        continue;
diff -r 6a187da7e2ad -r 89c69c642deb sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Thu Oct 03 22:29:17 2019 +0000
+++ b/sys/kern/kern_lwp.c       Thu Oct 03 22:48:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.203 2019/09/30 21:13:33 kamil Exp $     */
+/*     $NetBSD: kern_lwp.c,v 1.204 2019/10/03 22:48:44 kamil Exp $     */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.203 2019/09/30 21:13:33 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.204 2019/10/03 22:48:44 kamil Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -408,6 +408,11 @@
                return (EDEADLK);
        }
 
+       if ((t->l_flag & LW_DBGSUSPEND) != 0) {
+               lwp_unlock(t);
+               return 0;
+       }
+
        error = 0;
 
        switch (t->l_stat) {
@@ -472,7 +477,7 @@
 
        l->l_flag &= ~LW_WSUSPEND;
 
-       if (l->l_stat != LSSUSPENDED) {
+       if (l->l_stat != LSSUSPENDED || (l->l_flag & LW_DBGSUSPEND) != 0) {
                lwp_unlock(l);
                return;
        }
@@ -497,6 +502,8 @@
 
        lwp_lock(l);
 
+       KASSERT((l->l_flag & LW_DBGSUSPEND) == 0);
+
        /* If not stopped, then just bail out. */
        if (l->l_stat != LSSTOP) {
                lwp_unlock(l);
diff -r 6a187da7e2ad -r 89c69c642deb sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Thu Oct 03 22:29:17 2019 +0000
+++ b/sys/kern/kern_sig.c       Thu Oct 03 22:48:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.365 2019/09/30 21:13:33 kamil Exp $     */
+/*     $NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 kamil Exp $     */
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.365 2019/09/30 21:13:33 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -1108,11 +1108,20 @@
 
        SDT_PROBE(proc, kernel, , signal__send, l, p, sig, 0, 0);
 
+       lwp_lock(l);
+       if (__predict_false((l->l_flag & LW_DBGSUSPEND) != 0)) {
+               if ((prop & SA_KILL) != 0)
+                       l->l_flag &= ~LW_DBGSUSPEND;
+               else {
+                       lwp_unlock(l);
+                       return 0;
+               }
+       }
+
        /*
         * Have the LWP check for signals.  This ensures that even if no LWP
         * is found to take the signal immediately, it should be taken soon.
         */
-       lwp_lock(l);
        l->l_flag |= LW_PENDSIG;
 
        /*
@@ -2179,7 +2188,8 @@
                        LIST_FOREACH(t, &p->p_lwps, l_sibling) {
                                lwp_lock(t);
                                if (t == l) {
-                                       t->l_flag &= ~LW_WSUSPEND;
+                                       t->l_flag &=
+                                           ~(LW_WSUSPEND | LW_DBGSUSPEND);
                                        lwp_unlock(t);
                                        continue;
                                }
@@ -2376,7 +2386,7 @@
 
        LIST_FOREACH(l, &p->p_lwps, l_sibling) {
                lwp_lock(l);
-               if (l->l_stat != LSSTOP) {
+               if (l->l_stat != LSSTOP || (l->l_flag & LW_DBGSUSPEND) != 0) {
                        lwp_unlock(l);
                        continue;
                }
diff -r 6a187da7e2ad -r 89c69c642deb sys/kern/kern_synch.c
--- a/sys/kern/kern_synch.c     Thu Oct 03 22:29:17 2019 +0000
+++ b/sys/kern/kern_synch.c     Thu Oct 03 22:48:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_synch.c,v 1.323 2019/02/03 03:19:28 mrg Exp $     */
+/*     $NetBSD: kern_synch.c,v 1.324 2019/10/03 22:48:44 kamil Exp $   */
 
 /*-
  * Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.323 2019/02/03 03:19:28 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.324 2019/10/03 22:48:44 kamil Exp $");
 
 #include "opt_kstack.h"
 #include "opt_dtrace.h"
@@ -885,6 +885,7 @@
        struct cpu_info *ci;
 
        KASSERT((l->l_flag & LW_IDLE) == 0);
+       KASSERT((l->l_flag & LW_DBGSUSPEND) == 0);
        KASSERT(mutex_owned(p->p_lock));
        KASSERT(lwp_locked(l, NULL));
        KASSERT(l->l_mutex != l->l_cpu->ci_schedstate.spc_mutex);
diff -r 6a187da7e2ad -r 89c69c642deb sys/kern/sys_ptrace_common.c
--- a/sys/kern/sys_ptrace_common.c      Thu Oct 03 22:29:17 2019 +0000
+++ b/sys/kern/sys_ptrace_common.c      Thu Oct 03 22:48:44 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_ptrace_common.c,v 1.61 2019/10/01 21:49:50 kamil Exp $     */
+/*     $NetBSD: sys_ptrace_common.c,v 1.62 2019/10/03 22:48:44 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.61 2019/10/01 21:49:50 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.62 2019/10/03 22:48:44 kamil Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -787,9 +787,12 @@
        DPRINTF(("%s: lwp=%d request=%d\n", __func__, (*lt)->l_lid, rq));
        lwp_lock(*lt);
        if (rq == PT_SUSPEND)
-               (*lt)->l_flag |= LW_WSUSPEND;
-       else
-               (*lt)->l_flag &= ~LW_WSUSPEND;
+               (*lt)->l_flag |= LW_DBGSUSPEND;
+       else {
+               (*lt)->l_flag &= ~LW_DBGSUSPEND;
+               if ((*lt)->l_flag != LSSUSPENDED)
+                       (*lt)->l_stat = LSSTOP;
+       }
        lwp_unlock(*lt);
        return 0;
 }
@@ -1233,7 +1236,8 @@
                if (resume_all) {
 #ifdef PT_STEP
                        if (req == PT_STEP) {
-                               if (lt->l_flag & LW_WSUSPEND) {
+                               if (lt->l_flag &
+                                   (LW_WSUSPEND | LW_DBGSUSPEND)) {
                                        error = EDEADLK;
                                        break;
                                }
@@ -1242,7 +1246,9 @@
                        {
                                error = EDEADLK;
                                LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
-                                       if ((lt2->l_flag & LW_WSUSPEND) == 0) {
+                                       if ((lt2->l_flag &
+                                           (LW_WSUSPEND | LW_DBGSUSPEND)) == 0
+                                           ) {
                                                error = 0;
                                                break;
                                        }
@@ -1251,7 +1257,7 @@
                                        break;
                        }
                } else {
-                       if (lt->l_flag & LW_WSUSPEND) {
+                       if (lt->l_flag & (LW_WSUSPEND | LW_WSUSPEND)) {
                                error = EDEADLK;
                                break;
                        }



Home | Main Index | Thread Index | Old Index