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:
christos 2014-11-24 02:34:04 +00:00
parent 1c5f6cac84
commit 43dbf6a651

View File

@ -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;
} }