PR kern/36183 problem with ptrace and multithreaded processes
Fix the crashy test case that Thor provided.
This commit is contained in:
parent
bbaefad73d
commit
3c32363107
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: kern_lwp.c,v 1.126 2008/10/28 22:11:36 wrstuden Exp $ */
|
/* $NetBSD: kern_lwp.c,v 1.127 2009/02/04 21:17:39 ad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
@ -206,7 +206,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.126 2008/10/28 22:11:36 wrstuden Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.127 2009/02/04 21:17:39 ad Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_lockdebug.h"
|
#include "opt_lockdebug.h"
|
||||||
|
@ -1388,6 +1388,47 @@ lwp_drainrefs(struct lwp *l)
|
||||||
cv_wait(&p->p_lwpcv, p->p_lock);
|
cv_wait(&p->p_lwpcv, p->p_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return true if the specified LWP is 'alive'. Only p->p_lock need
|
||||||
|
* be held.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
lwp_alive(lwp_t *l)
|
||||||
|
{
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(l->l_proc->p_lock));
|
||||||
|
|
||||||
|
switch (l->l_stat) {
|
||||||
|
case LSSLEEP:
|
||||||
|
case LSRUN:
|
||||||
|
case LSONPROC:
|
||||||
|
case LSSTOP:
|
||||||
|
case LSSUSPENDED:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return first live LWP in the process.
|
||||||
|
*/
|
||||||
|
lwp_t *
|
||||||
|
lwp_find_first(proc_t *p)
|
||||||
|
{
|
||||||
|
lwp_t *l;
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(p->p_lock));
|
||||||
|
|
||||||
|
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
|
||||||
|
if (lwp_alive(l)) {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lwp_specific_key_create --
|
* lwp_specific_key_create --
|
||||||
* Create a key for subsystem lwp-specific data.
|
* Create a key for subsystem lwp-specific data.
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
/* $NetBSD: sys_process.c,v 1.145 2009/01/22 14:38:35 yamt Exp $ */
|
/* $NetBSD: sys_process.c,v 1.146 2009/02/04 21:17:39 ad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Andrew Doran.
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
|
@ -115,7 +118,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.145 2009/01/22 14:38:35 yamt Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.146 2009/02/04 21:17:39 ad Exp $");
|
||||||
|
|
||||||
#include "opt_ptrace.h"
|
#include "opt_ptrace.h"
|
||||||
#include "opt_ktrace.h"
|
#include "opt_ktrace.h"
|
||||||
|
@ -337,10 +340,16 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == 0)
|
if (error == 0) {
|
||||||
error = kauth_authorize_process(l->l_cred,
|
error = kauth_authorize_process(l->l_cred,
|
||||||
KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
|
KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
if (error == 0) {
|
||||||
|
lt = lwp_find_first(t);
|
||||||
|
if (lt == NULL)
|
||||||
|
error = ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
mutex_exit(proc_lock);
|
mutex_exit(proc_lock);
|
||||||
|
@ -351,16 +360,6 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
||||||
|
|
||||||
/* Do single-step fixup if needed. */
|
/* Do single-step fixup if needed. */
|
||||||
FIX_SSTEP(t);
|
FIX_SSTEP(t);
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX NJWLWP
|
|
||||||
*
|
|
||||||
* The entire ptrace interface needs work to be useful to a
|
|
||||||
* process with multiple LWPs. For the moment, we'll kluge
|
|
||||||
* this; memory access will be fine, but register access will
|
|
||||||
* be weird.
|
|
||||||
*/
|
|
||||||
lt = LIST_FIRST(&t->p_lwps);
|
|
||||||
KASSERT(lt != NULL);
|
KASSERT(lt != NULL);
|
||||||
lwp_addref(lt);
|
lwp_addref(lt);
|
||||||
|
|
||||||
|
@ -641,7 +640,7 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
||||||
lwp_delref(lt);
|
lwp_delref(lt);
|
||||||
mutex_enter(t->p_lock);
|
mutex_enter(t->p_lock);
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
lt = LIST_FIRST(&t->p_lwps);
|
lt = lwp_find_first(t);
|
||||||
else {
|
else {
|
||||||
lt = lwp_find(t, tmp);
|
lt = lwp_find(t, tmp);
|
||||||
if (lt == NULL) {
|
if (lt == NULL) {
|
||||||
|
@ -651,7 +650,7 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
||||||
}
|
}
|
||||||
lt = LIST_NEXT(lt, l_sibling);
|
lt = LIST_NEXT(lt, l_sibling);
|
||||||
}
|
}
|
||||||
while (lt != NULL && lt->l_stat == LSZOMB)
|
while (lt != NULL && !lwp_alive(lt))
|
||||||
lt = LIST_NEXT(lt, l_sibling);
|
lt = LIST_NEXT(lt, l_sibling);
|
||||||
pl.pl_lwpid = 0;
|
pl.pl_lwpid = 0;
|
||||||
pl.pl_event = 0;
|
pl.pl_event = 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* $NetBSD: lwp.h,v 1.116 2009/01/11 02:45:55 christos Exp $ */
|
/* $NetBSD: lwp.h,v 1.117 2009/02/04 21:17:39 ad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
@ -282,6 +282,8 @@ int lwp_trylock(lwp_t *);
|
||||||
void lwp_addref(lwp_t *);
|
void lwp_addref(lwp_t *);
|
||||||
void lwp_delref(lwp_t *);
|
void lwp_delref(lwp_t *);
|
||||||
void lwp_drainrefs(lwp_t *);
|
void lwp_drainrefs(lwp_t *);
|
||||||
|
bool lwp_alive(lwp_t *);
|
||||||
|
lwp_t *lwp_find_first(proc_t *);
|
||||||
|
|
||||||
/* Flags for _lwp_wait1 */
|
/* Flags for _lwp_wait1 */
|
||||||
#define LWPWAIT_EXITCONTROL 0x00000001
|
#define LWPWAIT_EXITCONTROL 0x00000001
|
||||||
|
|
Loading…
Reference in New Issue