Don't return early when the incorrect size is passed to some of the
ptrace actions. Leaves locks dangling and causes panics with lockdebug. XXX: Pullup 7
This commit is contained in:
parent
1c5f6cac84
commit
43dbf6a651
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: sys_process.c,v 1.164 2014/09/21 17:17:15 christos Exp $ */
|
/* $NetBSD: sys_process.c,v 1.165 2014/11/24 02:34:04 christos Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||||
@ -118,7 +118,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.164 2014/09/21 17:17:15 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.165 2014/11/24 02:34:04 christos Exp $");
|
||||||
|
|
||||||
#include "opt_ptrace.h"
|
#include "opt_ptrace.h"
|
||||||
#include "opt_ktrace.h"
|
#include "opt_ktrace.h"
|
||||||
@ -140,6 +140,13 @@ __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.164 2014/09/21 17:17:15 christos E
|
|||||||
#include <machine/reg.h>
|
#include <machine/reg.h>
|
||||||
|
|
||||||
#ifdef PTRACE
|
#ifdef PTRACE
|
||||||
|
|
||||||
|
# ifdef DEBUG
|
||||||
|
# define DPRINTF(a) uprintf a
|
||||||
|
# else
|
||||||
|
# define DPRINTF(a)
|
||||||
|
# endif
|
||||||
|
|
||||||
static kauth_listener_t ptrace_listener;
|
static kauth_listener_t ptrace_listener;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -398,7 +405,7 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
* different signal delivery semantics),
|
* different signal delivery semantics),
|
||||||
*/
|
*/
|
||||||
if (ISSET(t->p_slflag, PSL_FSTRACE)) {
|
if (ISSET(t->p_slflag, PSL_FSTRACE)) {
|
||||||
uprintf("file system traced\n");
|
DPRINTF(("file system traced\n"));
|
||||||
error = EBUSY;
|
error = EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -407,8 +414,8 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
* (3) it's not being traced by _you_, or
|
* (3) it's not being traced by _you_, or
|
||||||
*/
|
*/
|
||||||
if (t->p_pptr != p) {
|
if (t->p_pptr != p) {
|
||||||
uprintf("parent %d != %d\n", t->p_pptr->p_pid,
|
DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid,
|
||||||
p->p_pid);
|
p->p_pid));
|
||||||
error = EBUSY;
|
error = EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -417,8 +424,8 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
* (4) it's not currently stopped.
|
* (4) it's not currently stopped.
|
||||||
*/
|
*/
|
||||||
if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
|
if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
|
||||||
uprintf("stat %d flag %d\n", t->p_stat,
|
DPRINTF(("stat %d flag %d\n", t->p_stat,
|
||||||
!t->p_waited);
|
!t->p_waited));
|
||||||
error = EBUSY;
|
error = EBUSY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -770,8 +777,12 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
goto sendsig;
|
goto sendsig;
|
||||||
|
|
||||||
case PT_GET_EVENT_MASK:
|
case PT_GET_EVENT_MASK:
|
||||||
if (SCARG(uap, data) != sizeof(pe))
|
if (SCARG(uap, data) != sizeof(pe)) {
|
||||||
return EINVAL;
|
DPRINTF(("ptrace(%d): %d != %zu\n", req,
|
||||||
|
SCARG(uap, data), sizeof(pe)));
|
||||||
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
memset(&pe, 0, sizeof(pe));
|
memset(&pe, 0, sizeof(pe));
|
||||||
pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ?
|
pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ?
|
||||||
PTRACE_FORK : 0;
|
PTRACE_FORK : 0;
|
||||||
@ -779,8 +790,12 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SET_EVENT_MASK:
|
case PT_SET_EVENT_MASK:
|
||||||
if (SCARG(uap, data) != sizeof(pe))
|
if (SCARG(uap, data) != sizeof(pe)) {
|
||||||
return EINVAL;
|
DPRINTF(("ptrace(%d): %d != %zu\n", req,
|
||||||
|
SCARG(uap, data), sizeof(pe)));
|
||||||
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))) != 0)
|
if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))) != 0)
|
||||||
return error;
|
return error;
|
||||||
if (pe.pe_set_event & PTRACE_FORK)
|
if (pe.pe_set_event & PTRACE_FORK)
|
||||||
@ -790,8 +805,12 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_GET_PROCESS_STATE:
|
case PT_GET_PROCESS_STATE:
|
||||||
if (SCARG(uap, data) != sizeof(ps))
|
if (SCARG(uap, data) != sizeof(ps)) {
|
||||||
return EINVAL;
|
DPRINTF(("ptrace(%d): %d != %zu\n", req,
|
||||||
|
SCARG(uap, data), sizeof(ps)));
|
||||||
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
memset(&ps, 0, sizeof(ps));
|
memset(&ps, 0, sizeof(ps));
|
||||||
if (t->p_fpid) {
|
if (t->p_fpid) {
|
||||||
ps.pe_report_event = PTRACE_FORK;
|
ps.pe_report_event = PTRACE_FORK;
|
||||||
@ -802,6 +821,8 @@ sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
|
|||||||
|
|
||||||
case PT_LWPINFO:
|
case PT_LWPINFO:
|
||||||
if (SCARG(uap, data) != sizeof(pl)) {
|
if (SCARG(uap, data) != sizeof(pl)) {
|
||||||
|
DPRINTF(("ptrace(%d): %d != %zu\n", req,
|
||||||
|
SCARG(uap, data), sizeof(pl)));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user