Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167362182
D58247.id182096.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D58247.id182096.diff
View Options
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1005,6 +1005,16 @@
psr32->sr_error = psr->sr_error;
}
+static void
+ptrace_sc_ret32_to_ret(const struct ptrace_sc_ret32 *psr32,
+ struct ptrace_sc_ret *psr)
+{
+ bzero(psr, sizeof(*psr));
+ psr->sr_retval[0] = psr32->sr_retval[0];
+ psr->sr_retval[1] = psr32->sr_retval[1];
+ psr->sr_error = psr32->sr_error;
+}
+
int
freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
{
@@ -1051,6 +1061,15 @@
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);
+ }
+ break;
case PT_LWPINFO:
if (uap->data > sizeof(r32.pl))
return (EINVAL);
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -66,10 +66,11 @@
if (__predict_false(td->td_cowgen != atomic_load_int(&p->p_cowgen)))
thread_cow_update(td);
traced = (p->p_flag & P_TRACED) != 0;
- if (__predict_false(traced || td->td_dbgflags & TDB_USERWR)) {
+ if (__predict_false(traced || (td->td_dbgflags & (TDB_USERWR |
+ TDB_SET_SC_RET)) != 0)) {
PROC_LOCK(p);
MPASS((td->td_dbgflags & TDB_BOUNDARY) == 0);
- td->td_dbgflags &= ~TDB_USERWR;
+ td->td_dbgflags &= ~(TDB_USERWR | TDB_SET_SC_RET);
if (traced)
td->td_dbgflags |= TDB_SCE;
PROC_UNLOCK(p);
@@ -97,7 +98,10 @@
ptracestop((td), SIGTRAP, NULL);
PROC_UNLOCK(p);
- if ((td->td_dbgflags & TDB_USERWR) != 0) {
+ if ((td->td_dbgflags & TDB_SET_SC_RET) != 0) {
+ error = td->td_errno;
+ goto retval;
+ } else if ((td->td_dbgflags & TDB_USERWR) != 0) {
/*
* Reread syscall number and arguments if debugger
* modified registers or memory.
@@ -201,7 +205,7 @@
td->td_retval[1]);
if (__predict_false(traced)) {
PROC_LOCK(p);
- td->td_dbgflags &= ~(TDB_SCE | TDB_BOUNDARY);
+ td->td_dbgflags &= ~(TDB_SCE | TDB_BOUNDARY | TDB_SET_SC_RET);
PROC_UNLOCK(p);
}
(p->p_sysent->sv_set_syscall_retval)(td, error);
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -752,6 +752,12 @@
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));
+ break;
case PT_GETREGS:
bzero(&r.reg, sizeof(r.reg));
break;
@@ -1340,6 +1346,24 @@
psr->sr_retval[1]);
break;
+ case PT_SET_SC_RET:
+ if ((td2->td_dbgflags & TDB_SCE) == 0
+#ifdef COMPAT_FREEBSD32
+ || (wrap32 && !safe)
+#endif
+ ) {
+ error = EINVAL;
+ break;
+ }
+ psr = addr;
+ td2->td_errno = psr->sr_error;
+ if (td2->td_errno == 0) {
+ td2->td_retval[0] = psr->sr_retval[0];
+ td2->td_retval[1] = psr->sr_retval[1];
+ }
+ td2->td_dbgflags |= TDB_SET_SC_RET;
+ break;
+
case PT_STEP:
case PT_CONTINUE:
case PT_TO_SCE:
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -531,6 +531,7 @@
#define TDB_BOUNDARY 0x00008000 /* ptracestop() at boundary */
#define TDB_COREDUMPREQ 0x00010000 /* Coredump request */
#define TDB_SCREMOTEREQ 0x00020000 /* Remote syscall request */
+#define TDB_SET_SC_RET 0x00040000 /* PT_SET_SC_RET applied */
/*
* "Private" flags kept in td_pflags:
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -85,6 +85,7 @@
#define PT_GETREGSET 42 /* Get a target register set */
#define PT_SETREGSET 43 /* Set a target register set */
#define PT_SC_REMOTE 44 /* Execute a syscall */
+#define PT_SET_SC_RET 45 /* Set (fake) syscall results */
#define PT_FIRSTMACH 64 /* for machine-specific requests */
#define PT_LASTMACH 127
@@ -166,7 +167,7 @@
};
#endif
-/* Argument structure for PT_GET_SC_RET. */
+/* Argument structure for PT_GET_SC_RET and PT_SET_SC_RET. */
struct ptrace_sc_ret {
syscallarg_t sr_retval[2]; /* Only valid if sr_error == 0. */
int sr_error;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 22, 8:06 AM (16 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37068877
Default Alt Text
D58247.id182096.diff (4 KB)
Attached To
Mode
D58247: ptrace(2): PT_SET_SC_RET request
Attached
Detach File
Event Timeline
Log In to Comment