From nobody Fri Aug 28 12:05:06 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hWcX34Gnkz6qH90 for ; Fri, 28 Aug 2026 12:05:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hWcX317Cwz3Bs3 for ; Fri, 28 Aug 2026 12:05:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787918707; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=48jeCUxtbz31ftzW+FIDibE7QlgcXabzuaz0oa1T8a4=; b=BT9JPW8Wop1LH1QKPgCK3H9UkkeYbtqkR7MDz+opuNlCUYjkFp2MJEHM4x6d1ATZh+24qP OG8FUeYuzSU3G6yj8DblMAFZeqjLf89MiLbULPKbYx7YtbAydGhofBrvmFzumHPlGzULRu 7sYX3iw0HUSyFZRvOJ6KEjVRX9/Rq1RE1YpS0Gw4Tc4ED4e5I4fm4zYI5stdoC0/wiJ1vU Q3SCr9ElNBpzW94wTEgqqgr90637PZlvnn3NP4jLmnR7+0Q3LCdvaCraTYcwAUoCrIDQCi 1m1n62RDf8hFwTTSG2AcDNwtVGva1jqFPtjpexErfrLwPzuJzDPAnMIxUdmJzQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787918707; a=rsa-sha256; cv=none; b=wjDpCCnwTRiBeU5VdlI0ssoY7On4yp5ebJ9UdCxClxEqROao3Kby+saLMmcLiJ9hKLivKM 3YfAyHQYB0tT270LN7pdbTxH0mA4hg/hgKlTdI4SnuXqlXxAQV4bTJez5KUUYcEK++CQg4 Lb8OZne024f8dOUhZWqHzBVXyQXJVKSkaqvPv7L80nQ28gr/CjlyAftwOajqmHLZwgOjuZ T7mAOS0Jb3rWMRPUIvDmGNNo940hEScSg6wwcjKi9lAAqHZ3mMoPsAGCvynaHDpkReBw3w Svixp3A4Y3Alqvl/8sdL0BrtfZVSj6e6hz3Gkl44MVT4hMw9Y/GJPui1X4iNSw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787918707; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=48jeCUxtbz31ftzW+FIDibE7QlgcXabzuaz0oa1T8a4=; b=AGk0ejVebk11dKiLrQ5ia3XmoLf4/aTnIuXRX60fvfvcPt5cbyJ1EOksB2H0CMtimycFHb LcPbV9W3+ZIqcp65B3esYo5jVR/kCQbiQNJMJGLvHZAl5nwBEDWF0gIInuQmd81qopYQ3O 7F66DPYYNx4NDlfl2jdFVx1E5vl7cAZJAxdlQPzfsiL5Syn13ugRyUj7uL7SZNmOtHlIfF tI4PZYd3Edm1Xw2MJ7r8EtRuQtS9h4X5WcRyF59on/95A58hIyhxN3Nq2M8rbtrYFbnjf4 iVlMtok0N7BqMW4Q06Jmyyok1jMcg7X+8Ctne/oPS4/k9KnzahfZR27ua8pomQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hWcX26V6Nz18Lq for ; Fri, 28 Aug 2026 12:05:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 257a3 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 28 Aug 2026 12:05:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 9cea869940f1 - main - ptrace: split sys_ptrace()/freebsd32_ptrace() List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 9cea869940f197d558f640b6851d44a213be9e8a Auto-Submitted: auto-generated Date: Fri, 28 Aug 2026 12:05:06 +0000 Message-Id: <6a917972.257a3.2108578b@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=9cea869940f197d558f640b6851d44a213be9e8a commit 9cea869940f197d558f640b6851d44a213be9e8a Author: Konstantin Belousov AuthorDate: 2026-07-19 21:33:54 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-28 11:52:32 +0000 ptrace: split sys_ptrace()/freebsd32_ptrace() The code to handle copyin and copyout of the structured parameters is moved into the helpers. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58586 --- sys/compat/freebsd32/freebsd32_misc.c | 129 +++++++++++++++++----------------- sys/kern/sys_process.c | 114 ++++++++++++++++-------------- sys/sys/ptrace.h | 2 + 3 files changed, 128 insertions(+), 117 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 08e15140317d..5b5a13a16de1 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1015,8 +1015,9 @@ ptrace_sc_ret32_to_ret(const struct ptrace_sc_ret32 *psr32, psr->sr_error = psr32->sr_error; } -int -freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) +static int +freebsd32_ptrace_useraction(struct thread *td, int req, pid_t pid, + void *uaddr, int udata) { union { struct ptrace_io_desc piod; @@ -1050,39 +1051,32 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) if (!allow_ptrace) return (ENOSYS); - error = 0; - AUDIT_ARG_PID(uap->pid); - AUDIT_ARG_CMD(uap->req); - AUDIT_ARG_VALUE(uap->data); + error = 0; addr = &r; - data = uap->data; - switch (uap->req) { + data = udata; + + switch (req) { case PT_GET_EVENT_MASK: case PT_GET_SC_ARGS: case PT_GET_SC_RET: break; case PT_SET_SC_RET: - if (uap->data != sizeof(r32.psr)) { - error = EINVAL; - } else { - error = copyin(uap->addr, &r32.psr, sizeof(r32.psr)); - if (error == 0) - ptrace_sc_ret32_to_ret(&r32.psr, &r.psr); - } + error = udata != sizeof(r32.psr) ? EINVAL : + copyin(uaddr, &r32.psr, sizeof(r32.psr)); + if (error == 0) + ptrace_sc_ret32_to_ret(&r32.psr, &r.psr); break; case PT_LWPINFO: - if (uap->data > sizeof(r32.pl)) + if (udata > sizeof(r32.pl)) return (EINVAL); - /* * Pass size of native structure in 'data'. Truncate * if necessary to avoid siginfo. */ - data = sizeof(r.pl); - if (uap->data < offsetof(struct ptrace_lwpinfo32, pl_siginfo) + - sizeof(struct __siginfo32)) - data = offsetof(struct ptrace_lwpinfo, pl_siginfo); + data = udata < offsetof(struct ptrace_lwpinfo32, + pl_siginfo) + sizeof(struct __siginfo32) ? + offsetof(struct ptrace_lwpinfo, pl_siginfo) : sizeof(r.pl); break; case PT_GETREGS: bzero(&r.reg, sizeof(r.reg)); @@ -1094,17 +1088,17 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) bzero(&r.dbreg, sizeof(r.dbreg)); break; case PT_SETREGS: - error = copyin(uap->addr, &r.reg, sizeof(r.reg)); + error = copyin(uaddr, &r.reg, sizeof(r.reg)); break; case PT_SETFPREGS: - error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg)); + error = copyin(uaddr, &r.fpreg, sizeof(r.fpreg)); break; case PT_SETDBREGS: - error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg)); + error = copyin(uaddr, &r.dbreg, sizeof(r.dbreg)); break; case PT_GETREGSET: case PT_SETREGSET: - error = copyin(uap->addr, &r32.vec, sizeof(r32.vec)); + error = copyin(uaddr, &r32.vec, sizeof(r32.vec)); if (error != 0) break; @@ -1112,14 +1106,12 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) r.vec.iov_base = PTRIN(r32.vec.iov_base); break; case PT_SET_EVENT_MASK: - if (uap->data != sizeof(r.ptevents)) - error = EINVAL; - else - error = copyin(uap->addr, &r.ptevents, uap->data); + error = udata != sizeof(r.ptevents) ? EINVAL : + copyin(uaddr, &r.ptevents, udata); break; case PT_IO: - error = copyin(uap->addr, &r32.piod, sizeof(r32.piod)); - if (error) + error = copyin(uaddr, &r32.piod, sizeof(r32.piod)); + if (error != 0) break; CP(r32.piod, r.piod, piod_op); PTRIN_CP(r32.piod, r.piod, piod_offs); @@ -1127,8 +1119,8 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) CP(r32.piod, r.piod, piod_len); break; case PT_VM_ENTRY: - error = copyin(uap->addr, &r32.pve, sizeof(r32.pve)); - if (error) + error = copyin(uaddr, &r32.pve, sizeof(r32.pve)); + if (error != 0) break; CP(r32.pve, r.pve, pve_entry); @@ -1143,21 +1135,18 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) PTRIN_CP(r32.pve, r.pve, pve_path); break; case PT_COREDUMP: - if (uap->data != sizeof(r32.pc)) - error = EINVAL; - else - error = copyin(uap->addr, &r32.pc, uap->data); + error = udata != sizeof(r32.pc) ? EINVAL : + copyin(uaddr, &r32.pc, udata); + if (error != 0) + break; CP(r32.pc, r.pc, pc_fd); CP(r32.pc, r.pc, pc_flags); r.pc.pc_limit = PAIR32TO64(off_t, r32.pc.pc_limit); data = sizeof(r.pc); break; case PT_SC_REMOTE: - if (uap->data != sizeof(r32.sr)) { - error = EINVAL; - break; - } - error = copyin(uap->addr, &r32.sr, uap->data); + error = udata != sizeof(r32.sr) ? EINVAL : + copyin(uaddr, &r32.sr, udata); if (error != 0) break; CP(r32.sr, r.sr, pscr_syscall); @@ -1175,9 +1164,9 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) r.sr.pscr_args = pscr_args; break; case PT_GET_CHILDREN: - if (uap->addr == NULL) + if (uaddr == NULL) addr = NULL; - else if (uap->data < 0) + else if (udata < 0) error = EINVAL; else addr = &r.children; @@ -1186,17 +1175,17 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) error = EINVAL; break; default: - addr = uap->addr; + addr = uaddr; break; } - if (error) + if (error != 0) return (error); - error = kern_ptrace(td, uap->req, uap->pid, addr, data); - if (error) + error = ptrace_action(td, req, pid, addr, data); + if (error != 0) return (error); - switch (uap->req) { + switch (req) { case PT_VM_ENTRY: CP(r.pve, r32.pve, pve_entry); CP(r.pve, r32.pve, pve_timestamp); @@ -1207,53 +1196,51 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) CP(r.pve, r32.pve, pve_pathlen); CP(r.pve, r32.pve, pve_fileid); CP(r.pve, r32.pve, pve_fsid); - error = copyout(&r32.pve, uap->addr, sizeof(r32.pve)); + error = copyout(&r32.pve, uaddr, sizeof(r32.pve)); break; case PT_IO: CP(r.piod, r32.piod, piod_len); - error = copyout(&r32.piod, uap->addr, sizeof(r32.piod)); + error = copyout(&r32.piod, uaddr, sizeof(r32.piod)); break; case PT_GETREGS: - error = copyout(&r.reg, uap->addr, sizeof(r.reg)); + error = copyout(&r.reg, uaddr, sizeof(r.reg)); break; case PT_GETFPREGS: - error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg)); + error = copyout(&r.fpreg, uaddr, sizeof(r.fpreg)); break; case PT_GETDBREGS: - error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg)); + error = copyout(&r.dbreg, uaddr, sizeof(r.dbreg)); break; case PT_GETREGSET: r32.vec.iov_len = r.vec.iov_len; - error = copyout(&r32.vec, uap->addr, sizeof(r32.vec)); + error = copyout(&r32.vec, uaddr, sizeof(r32.vec)); break; case PT_GET_EVENT_MASK: /* NB: The size in uap->data is validated in kern_ptrace(). */ - error = copyout(&r.ptevents, uap->addr, uap->data); + error = copyout(&r.ptevents, uaddr, udata); break; case PT_LWPINFO: ptrace_lwpinfo_to32(&r.pl, &r32.pl); - error = copyout(&r32.pl, uap->addr, uap->data); + error = copyout(&r32.pl, uaddr, udata); break; case PT_GET_SC_ARGS: for (i = 0; i < nitems(r.args); i++) r32.args[i] = (uint32_t)r.args[i]; - error = copyout(r32.args, uap->addr, MIN(uap->data, - sizeof(r32.args))); + error = copyout(r32.args, uaddr, MIN(udata, sizeof(r32.args))); break; case PT_GET_SC_RET: ptrace_sc_ret_to32(&r.psr, &r32.psr); - error = copyout(&r32.psr, uap->addr, MIN(uap->data, - sizeof(r32.psr))); + error = copyout(&r32.psr, uaddr, MIN(udata, sizeof(r32.psr))); break; case PT_SC_REMOTE: ptrace_sc_ret_to32(&r.sr.pscr_ret, &r32.sr.pscr_ret); - error = copyout(&r32.sr.pscr_ret, uap->addr + + error = copyout(&r32.sr.pscr_ret, (char *)uaddr + offsetof(struct ptrace_sc_remote32, pscr_ret), sizeof(r32.psr)); break; case PT_GET_CHILDREN: - if (uap->addr != 0) { - error = copyout(r.children, uap->addr, + if (uaddr != NULL) { + error = copyout(r.children, uaddr, td->td_retval[0] * sizeof(struct ptrace_child)); free(r.children, M_TEMP); } @@ -1263,6 +1250,20 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) return (error); } +int +freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap) +{ + int error; + + AUDIT_ARG_PID(uap->pid); + AUDIT_ARG_CMD(uap->req); + AUDIT_ARG_VALUE(uap->data); + + error = freebsd32_ptrace_useraction(td, uap->req, uap->pid, + uap->addr, uap->data); + return (error); +} + int freebsd32_copyinuio(const struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) { diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 46848ca150c0..39196561928c 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -714,8 +714,9 @@ struct ptrace_args { }; #endif -int -sys_ptrace(struct thread *td, struct ptrace_args *uap) +static int +ptrace_useraction(struct thread *td, int req, pid_t pid, void *uaddr, + int udata) { /* * XXX this obfuscation is to reduce stack usage, but the register @@ -742,23 +743,19 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap) if (!allow_ptrace) return (ENOSYS); - error = 0; - AUDIT_ARG_PID(uap->pid); - AUDIT_ARG_CMD(uap->req); - AUDIT_ARG_VALUE(uap->data); + error = 0; addr = &r; - switch (uap->req) { + + switch (req) { case PT_GET_EVENT_MASK: case PT_LWPINFO: case PT_GET_SC_ARGS: case PT_GET_SC_RET: break; case PT_SET_SC_RET: - if (uap->data != sizeof(r.psr)) - error = EINVAL; - else - error = copyin(uap->addr, &r.psr, sizeof(r.psr)); + error = udata != sizeof(r.psr) ? EINVAL : + copyin(uaddr, &r.psr, sizeof(r.psr)); break; case PT_GETREGS: bzero(&r.reg, sizeof(r.reg)); @@ -771,41 +768,34 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap) break; case PT_GETREGSET: case PT_SETREGSET: - error = copyin(uap->addr, &r.vec, sizeof(r.vec)); + error = copyin(uaddr, &r.vec, sizeof(r.vec)); break; case PT_SETREGS: - error = copyin(uap->addr, &r.reg, sizeof(r.reg)); + error = copyin(uaddr, &r.reg, sizeof(r.reg)); break; case PT_SETFPREGS: - error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg)); + error = copyin(uaddr, &r.fpreg, sizeof(r.fpreg)); break; case PT_SETDBREGS: - error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg)); + error = copyin(uaddr, &r.dbreg, sizeof(r.dbreg)); break; case PT_SET_EVENT_MASK: - if (uap->data != sizeof(r.ptevents)) - error = EINVAL; - else - error = copyin(uap->addr, &r.ptevents, uap->data); + error = udata != sizeof(r.ptevents) ? EINVAL : + copyin(uaddr, &r.ptevents, udata); break; case PT_IO: - error = copyin(uap->addr, &r.piod, sizeof(r.piod)); + error = copyin(uaddr, &r.piod, sizeof(r.piod)); break; case PT_VM_ENTRY: - error = copyin(uap->addr, &r.pve, sizeof(r.pve)); + error = copyin(uaddr, &r.pve, sizeof(r.pve)); break; case PT_COREDUMP: - if (uap->data != sizeof(r.pc)) - error = EINVAL; - else - error = copyin(uap->addr, &r.pc, uap->data); + error = udata != sizeof(r.pc) ? EINVAL : + copyin(uaddr, &r.pc, udata); break; case PT_SC_REMOTE: - if (uap->data != sizeof(r.sr)) { - error = EINVAL; - break; - } - error = copyin(uap->addr, &r.sr, uap->data); + error = udata != sizeof(r.sr) ? EINVAL : + copyin(uaddr, &r.sr, udata); if (error != 0) break; if (r.sr.pscr_nargs > nitems(td->td_sa.args)) { @@ -819,9 +809,9 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap) r.sr.pscr_args = pscr_args; break; case PT_GET_CHILDREN: - if (uap->addr == NULL) + if (uaddr == NULL) addr = NULL; - else if (uap->data < 0) + else if (udata < 0) error = EINVAL; else addr = &r.children; @@ -830,59 +820,57 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap) error = EINVAL; break; default: - addr = uap->addr; + addr = uaddr; break; } if (error != 0) return (error); - error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data); + error = ptrace_action(td, req, pid, addr, udata); if (error != 0) return (error); - switch (uap->req) { + switch (req) { case PT_VM_ENTRY: - error = copyout(&r.pve, uap->addr, sizeof(r.pve)); + error = copyout(&r.pve, uaddr, sizeof(r.pve)); break; case PT_IO: - error = copyout(&r.piod, uap->addr, sizeof(r.piod)); + error = copyout(&r.piod, uaddr, sizeof(r.piod)); break; case PT_GETREGS: - error = copyout(&r.reg, uap->addr, sizeof(r.reg)); + error = copyout(&r.reg, uaddr, sizeof(r.reg)); break; case PT_GETFPREGS: - error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg)); + error = copyout(&r.fpreg, uaddr, sizeof(r.fpreg)); break; case PT_GETDBREGS: - error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg)); + error = copyout(&r.dbreg, uaddr, sizeof(r.dbreg)); break; case PT_GETREGSET: - error = copyout(&r.vec, uap->addr, sizeof(r.vec)); + error = copyout(&r.vec, uaddr, sizeof(r.vec)); break; case PT_GET_EVENT_MASK: - /* NB: The size in uap->data is validated in kern_ptrace(). */ - error = copyout(&r.ptevents, uap->addr, uap->data); + /* NB: The size in uap->data is validated in ptraceimpl(). */ + error = copyout(&r.ptevents, uaddr, udata); break; case PT_LWPINFO: - /* NB: The size in uap->data is validated in kern_ptrace(). */ - error = copyout(&r.pl, uap->addr, uap->data); + /* NB: The size in uap->data is validated in ptraceimpl(). */ + error = copyout(&r.pl, uaddr, udata); break; case PT_GET_SC_ARGS: - error = copyout(r.args, uap->addr, MIN(uap->data, - sizeof(r.args))); + error = copyout(r.args, uaddr, MIN(udata, sizeof(r.args))); break; case PT_GET_SC_RET: - error = copyout(&r.psr, uap->addr, MIN(uap->data, - sizeof(r.psr))); + error = copyout(&r.psr, uaddr, MIN(udata, sizeof(r.psr))); break; case PT_SC_REMOTE: - error = copyout(&r.sr.pscr_ret, uap->addr + + error = copyout(&r.sr.pscr_ret, (char *)uaddr + offsetof(struct ptrace_sc_remote, pscr_ret), sizeof(r.sr.pscr_ret)); break; case PT_GET_CHILDREN: - if (uap->addr != NULL) { - error = copyout(r.children, uap->addr, + if (uaddr != NULL) { + error = copyout(r.children, uaddr, td->td_retval[0] * sizeof(struct ptrace_child)); free(r.children, M_TEMP); } @@ -1056,7 +1044,7 @@ ptrace_sel_coredump_thread(struct proc *p) } int -kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) +ptrace_action(struct thread *td, int req, pid_t pid, void *addr, int data) { struct iovec iov; struct uio uio; @@ -2027,3 +2015,23 @@ fail: } #undef PROC_READ #undef PROC_WRITE + +int +kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) +{ + return (ptrace_action(td, req, pid, addr, data)); +} + +int +sys_ptrace(struct thread *td, struct ptrace_args *uap) +{ + int error; + + AUDIT_ARG_PID(uap->pid); + AUDIT_ARG_CMD(uap->req); + AUDIT_ARG_VALUE(uap->data); + + error = ptrace_useraction(td, uap->req, uap->pid, uap->addr, + uap->data); + return (error); +} diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index 54669493ca75..50e7dba5c946 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -291,6 +291,8 @@ int proc_write_dbregs32(struct thread *_td, struct dbreg32 *_dbreg32); #endif void ptrace_unsuspend(struct proc *p); +int ptrace_action(struct thread *td, int req, pid_t pid, void *addr, + int data); extern bool allow_ptrace;