mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Add pdptrace(2)
Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58586
This commit is contained in:
1 parent
9cea869940
commit
f8c0616052
4 files changed
+91
-29
No files matched your search
@@ -1016,8 +1016,8 @@ ptrace_sc_ret32_to_ret(const struct ptrace_sc_ret32 *psr32,
|
||||
}
|
||||
|
||||
static int
|
||||
freebsd32_ptrace_useraction(struct thread *td, int req, pid_t pid,
|
||||
void *uaddr, int udata)
|
||||
freebsd32_ptrace_useraction(struct thread *td, int req, bool pd_mode, pid_t pid,
|
||||
int pfd, lwpid_t lwpid, void *uaddr, int udata)
|
||||
{
|
||||
union {
|
||||
struct ptrace_io_desc piod;
|
||||
@@ -1181,7 +1181,7 @@ freebsd32_ptrace_useraction(struct thread *td, int req, pid_t pid,
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = ptrace_action(td, req, pid, addr, data);
|
||||
error = ptrace_action(td, req, pd_mode, pid, pfd, lwpid, addr, data);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
@@ -1259,8 +1259,22 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
|
||||
AUDIT_ARG_CMD(uap->req);
|
||||
AUDIT_ARG_VALUE(uap->data);
|
||||
|
||||
error = freebsd32_ptrace_useraction(td, uap->req, uap->pid,
|
||||
uap->addr, uap->data);
|
||||
error = freebsd32_ptrace_useraction(td, uap->req, false, uap->pid,
|
||||
-1, -1, uap->addr, uap->data);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
freebsd32_pdptrace(struct thread *td, struct freebsd32_pdptrace_args *uap)
|
||||
{
|
||||
int error;
|
||||
|
||||
AUDIT_ARG_FD(uap->pfd);
|
||||
AUDIT_ARG_CMD(uap->req);
|
||||
AUDIT_ARG_VALUE(uap->data);
|
||||
|
||||
error = freebsd32_ptrace_useraction(td, uap->req, true, -1,
|
||||
uap->pfd, uap->lwpid, uap->addr, uap->data);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
+61
-22
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <sys/caprights.h>
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/ktr.h>
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/procdesc.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/reg.h>
|
||||
#include <sys/rwlock.h>
|
||||
@@ -715,8 +716,8 @@ struct ptrace_args {
|
||||
#endif
|
||||
|
||||
static int
|
||||
ptrace_useraction(struct thread *td, int req, pid_t pid, void *uaddr,
|
||||
int udata)
|
||||
ptrace_useraction(struct thread *td, int req, bool pd_mode, pid_t pid, int pfd,
|
||||
lwpid_t lwpid, void *uaddr, int udata)
|
||||
{
|
||||
/*
|
||||
* XXX this obfuscation is to reduce stack usage, but the register
|
||||
@@ -826,7 +827,7 @@ ptrace_useraction(struct thread *td, int req, pid_t pid, void *uaddr,
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
error = ptrace_action(td, req, pid, addr, udata);
|
||||
error = ptrace_action(td, req, pd_mode, pid, pfd, lwpid, addr, udata);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
@@ -1044,7 +1045,8 @@ ptrace_sel_coredump_thread(struct proc *p)
|
||||
}
|
||||
|
||||
int
|
||||
ptrace_action(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
ptrace_action(struct thread *td, int req, bool pd_mode, pid_t pid, int pfd,
|
||||
lwpid_t lwpid, void *addr, int data)
|
||||
{
|
||||
struct iovec iov;
|
||||
struct uio uio;
|
||||
@@ -1058,6 +1060,7 @@ ptrace_action(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
struct ptrace_coredump *pc;
|
||||
struct thr_coredump_req *tcq;
|
||||
struct thr_syscall_req *tsr;
|
||||
struct file *pfp;
|
||||
struct ptrace_child *children, *ptc;
|
||||
int error, num, num1, tmp;
|
||||
lwpid_t tid = 0, *buf;
|
||||
@@ -1069,6 +1072,7 @@ ptrace_action(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
curp = td->td_proc;
|
||||
proctree_locked = false;
|
||||
p2_req_set = false;
|
||||
pfp = NULL;
|
||||
|
||||
/* Lock proctree before locking the process. */
|
||||
switch (req) {
|
||||
@@ -1096,24 +1100,42 @@ ptrace_action(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
if (req == PT_TRACE_ME) {
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
} else {
|
||||
if (pid <= PID_MAX) {
|
||||
if ((p = pfind(pid)) == NULL) {
|
||||
if (proctree_locked)
|
||||
sx_xunlock(&proctree_lock);
|
||||
return (ESRCH);
|
||||
} else if (pd_mode) {
|
||||
if (!proctree_locked)
|
||||
sx_slock(&proctree_lock);
|
||||
error = fget_procdesc(td, pfd, &cap_ptrace_rights, EINVAL,
|
||||
&pfp, NULL, &p);
|
||||
if (!proctree_locked)
|
||||
sx_sunlock(&proctree_lock);
|
||||
if (error != 0)
|
||||
goto fail_proctree;
|
||||
pid = p->p_pid;
|
||||
if (lwpid != -1) {
|
||||
FOREACH_THREAD_IN_PROC(p, td2) {
|
||||
if (td2->td_tid == lwpid)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
td2 = tdfind(pid, -1);
|
||||
if (td2 == NULL) {
|
||||
if (proctree_locked)
|
||||
sx_xunlock(&proctree_lock);
|
||||
return (ESRCH);
|
||||
PROC_UNLOCK(p);
|
||||
error = ESRCH;
|
||||
goto fail_proctree;
|
||||
}
|
||||
p = td2->td_proc;
|
||||
tid = pid;
|
||||
pid = p->p_pid;
|
||||
tid = td2->td_tid;
|
||||
}
|
||||
} else if (pid <= PID_MAX) {
|
||||
if ((p = pfind(pid)) == NULL) {
|
||||
error = ESRCH;
|
||||
goto fail_proctree;
|
||||
}
|
||||
} else {
|
||||
td2 = tdfind(pid, -1);
|
||||
if (td2 == NULL) {
|
||||
error = ESRCH;
|
||||
goto fail_proctree;
|
||||
}
|
||||
p = td2->td_proc;
|
||||
tid = pid;
|
||||
pid = p->p_pid;
|
||||
}
|
||||
AUDIT_ARG_PROCESS(p);
|
||||
|
||||
@@ -2009,8 +2031,11 @@ fail:
|
||||
p->p_flag2 &= ~P2_PTRACEREQ;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
fail_proctree:
|
||||
if (proctree_locked)
|
||||
sx_xunlock(&proctree_lock);
|
||||
if (pfp != NULL)
|
||||
fdrop(pfp, td);
|
||||
return (error);
|
||||
}
|
||||
#undef PROC_READ
|
||||
@@ -2019,7 +2044,7 @@ fail:
|
||||
int
|
||||
kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
|
||||
{
|
||||
return (ptrace_action(td, req, pid, addr, data));
|
||||
return (ptrace_action(td, req, false, pid, -1, -1, addr, data));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2031,7 +2056,21 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
|
||||
AUDIT_ARG_CMD(uap->req);
|
||||
AUDIT_ARG_VALUE(uap->data);
|
||||
|
||||
error = ptrace_useraction(td, uap->req, uap->pid, uap->addr,
|
||||
uap->data);
|
||||
error = ptrace_useraction(td, uap->req, false, uap->pid, -1, -1,
|
||||
uap->addr, uap->data);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sys_pdptrace(struct thread *td, struct pdptrace_args *uap)
|
||||
{
|
||||
int error;
|
||||
|
||||
AUDIT_ARG_FD(uap->pfd);
|
||||
AUDIT_ARG_CMD(uap->req);
|
||||
AUDIT_ARG_VALUE(uap->data);
|
||||
|
||||
error = ptrace_useraction(td, uap->req, true, -1, uap->pfd, uap->lwpid,
|
||||
uap->addr, uap->data);
|
||||
return (error);
|
||||
}
|
||||
@@ -3442,5 +3442,14 @@
|
||||
int flags
|
||||
);
|
||||
}
|
||||
605 AUE_PDPTRACE STD {
|
||||
int pdptrace(
|
||||
int req,
|
||||
int pfd,
|
||||
int lwpid,
|
||||
_Inout_opt_ _Contains_long_ptr_ void *addr,
|
||||
int data
|
||||
);
|
||||
}
|
||||
|
||||
; vim: syntax=off
|
||||
+2
-2
@@ -291,8 +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);
|
||||
int ptrace_action(struct thread *td, int req, bool pd_mode, pid_t pid,
|
||||
int pfd, lwpid_t lwpid, void *addr, int data);
|
||||
|
||||
extern bool allow_ptrace;
|
||||
|
||||
|
||||
Reference in new issue
Block a user