Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140956509
D20901.id59586.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D20901.id59586.diff
View Options
Index: sys/kern/sys_process.c
===================================================================
--- sys/kern/sys_process.c
+++ sys/kern/sys_process.c
@@ -76,6 +76,11 @@
uint32_t piod_len;
};
+struct ptrace_sc_ret32 {
+ uint32_t sr_retval[2];
+ int sr_error;
+};
+
struct ptrace_vm_entry32 {
int pve_entry;
int pve_timestamp;
@@ -517,6 +522,17 @@
pl32->pl_syscall_code = pl->pl_syscall_code;
pl32->pl_syscall_narg = pl->pl_syscall_narg;
}
+
+static void
+ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
+ struct ptrace_sc_ret32 *psr32)
+{
+
+ bzero(psr32, sizeof(*psr32));
+ psr32->sr_retval[0] = psr->sr_retval[0];
+ psr32->sr_retval[1] = psr->sr_retval[1];
+ psr32->sr_error = psr->sr_error;
+}
#endif /* COMPAT_FREEBSD32 */
/*
@@ -579,6 +595,7 @@
struct ptrace_vm_entry32 pve32;
#endif
char args[sizeof(td->td_sa.args)];
+ struct ptrace_sc_ret psr;
int ptevents;
} r;
void *addr;
@@ -597,6 +614,7 @@
case PT_GET_EVENT_MASK:
case PT_LWPINFO:
case PT_GET_SC_ARGS:
+ case PT_GET_SC_RET:
break;
case PT_GETREGS:
BZERO(&r.reg, sizeof r.reg);
@@ -667,6 +685,10 @@
error = copyout(r.args, uap->addr, MIN(uap->data,
sizeof(r.args)));
break;
+ case PT_GET_SC_RET:
+ error = copyout(&r.psr, uap->addr, MIN(uap->data,
+ sizeof(r.psr)));
+ break;
}
return (error);
@@ -718,6 +740,7 @@
struct thread *td2 = NULL, *td3;
struct ptrace_io_desc *piod = NULL;
struct ptrace_lwpinfo *pl;
+ struct ptrace_sc_ret *psr;
int error, num, tmp;
int proctree_locked = 0;
lwpid_t tid = 0, *buf;
@@ -725,7 +748,11 @@
int wrap32 = 0, safe = 0;
struct ptrace_io_desc32 *piod32 = NULL;
struct ptrace_lwpinfo32 *pl32 = NULL;
- struct ptrace_lwpinfo plr;
+ struct ptrace_sc_ret32 *psr32 = NULL;
+ union {
+ struct ptrace_lwpinfo pl;
+ struct ptrace_sc_ret psr;
+ } r;
#endif
curp = td->td_proc;
@@ -1048,6 +1075,38 @@
bcopy(td2->td_sa.args, addr, td2->td_sa.narg *
sizeof(register_t));
break;
+
+ case PT_GET_SC_RET:
+ if ((td2->td_dbgflags & (TDB_SCX)) == 0
+#ifdef COMPAT_FREEBSD32
+ || (wrap32 && !safe)
+#endif
+ ) {
+ error = EINVAL;
+ break;
+ }
+#ifdef COMPAT_FREEBSD32
+ if (wrap32) {
+ psr = &r.psr;
+ psr32 = addr;
+ } else
+#endif
+ psr = addr;
+ bzero(psr, sizeof(*psr));
+ psr->sr_error = td2->td_errno;
+ if (psr->sr_error == 0) {
+ psr->sr_retval[0] = td2->td_retval[0];
+ psr->sr_retval[1] = td2->td_retval[1];
+ }
+#ifdef COMPAT_FREEBSD32
+ if (wrap32)
+ ptrace_sc_ret_to32(psr, psr32);
+#endif
+ CTR4(KTR_PTRACE,
+ "PT_GET_SC_RET: pid %d error %d retval %#lx,%#lx",
+ p->p_pid, psr->sr_error, psr->sr_retval[0],
+ psr->sr_retval[1]);
+ break;
case PT_STEP:
case PT_CONTINUE:
@@ -1334,7 +1393,7 @@
}
#ifdef COMPAT_FREEBSD32
if (wrap32) {
- pl = &plr;
+ pl = &r.pl;
pl32 = addr;
} else
#endif
Index: sys/sys/ptrace.h
===================================================================
--- sys/sys/ptrace.h
+++ sys/sys/ptrace.h
@@ -72,6 +72,7 @@
#define PT_SET_EVENT_MASK 26 /* set mask of optional events */
#define PT_GET_SC_ARGS 27 /* fetch syscall args */
+#define PT_GET_SC_RET 28 /* fetch syscall results */
#define PT_GETREGS 33 /* get general-purpose registers */
#define PT_SETREGS 34 /* set general-purpose registers */
@@ -155,6 +156,12 @@
};
#endif
+/* Argument structure for PT_GET_SC_RET. */
+struct ptrace_sc_ret {
+ register_t sr_retval[2]; /* Only valid if sr_error == 0. */
+ int sr_error;
+};
+
/* Argument structure for PT_VM_ENTRY. */
struct ptrace_vm_entry {
int pve_entry; /* Entry number used for iteration. */
Index: tests/sys/kern/ptrace_test.c
===================================================================
--- tests/sys/kern/ptrace_test.c
+++ tests/sys/kern/ptrace_test.c
@@ -3905,12 +3905,13 @@
}
/*
- * A simple test of PT_GET_SC_ARGS.
+ * A simple test of PT_GET_SC_ARGS and PT_GET_SC_RET.
*/
ATF_TC_WITHOUT_HEAD(ptrace__syscall_args);
ATF_TC_BODY(ptrace__syscall_args, tc)
{
struct ptrace_lwpinfo pl;
+ struct ptrace_sc_ret psr;
pid_t fpid, wpid;
register_t args[2];
int events, status;
@@ -3919,6 +3920,7 @@
if (fpid == 0) {
trace_me();
kill(getpid(), 0);
+ close(3);
exit(1);
}
@@ -3930,9 +3932,9 @@
/*
* Continue the process ignoring the signal, but enabling
- * syscall entry traps.
+ * syscall traps.
*/
- ATF_REQUIRE(ptrace(PT_TO_SCE, fpid, (caddr_t)1, 0) == 0);
+ ATF_REQUIRE(ptrace(PT_SYSCALL, fpid, (caddr_t)1, 0) == 0);
/*
* The next stop should be the syscall entry from getpid().
@@ -3948,6 +3950,25 @@
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+ /*
+ * The next stop should be the syscall exit from getpid().
+ */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX);
+ ATF_REQUIRE(pl.pl_syscall_code == SYS_getpid);
+
+ ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr,
+ sizeof(psr)) != -1);
+ ATF_REQUIRE(psr.sr_error == 0);
+ ATF_REQUIRE(psr.sr_retval[0] == wpid);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
/*
* The next stop should be the syscall entry from kill().
*/
@@ -3966,6 +3987,61 @@
ATF_REQUIRE(args[0] == wpid);
ATF_REQUIRE(args[1] == 0);
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /*
+ * The next stop should be the syscall exit from kill().
+ */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX);
+ ATF_REQUIRE(pl.pl_syscall_code == SYS_kill);
+
+ ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr,
+ sizeof(psr)) != -1);
+ ATF_REQUIRE(psr.sr_error == 0);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /*
+ * The next stop should be the syscall entry from close().
+ */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCE);
+ ATF_REQUIRE(pl.pl_syscall_code == SYS_close);
+ ATF_REQUIRE(pl.pl_syscall_narg == 1);
+
+ ATF_REQUIRE(ptrace(PT_GET_SC_ARGS, wpid, (caddr_t)args,
+ sizeof(args)) != -1);
+ ATF_REQUIRE(args[0] == 3);
+
+ ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
+
+ /*
+ * The next stop should be the syscall exit from close().
+ */
+ wpid = waitpid(fpid, &status, 0);
+ ATF_REQUIRE(wpid == fpid);
+ ATF_REQUIRE(WIFSTOPPED(status));
+ ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP);
+
+ ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1);
+ ATF_REQUIRE(pl.pl_flags & PL_FLAG_SCX);
+ ATF_REQUIRE(pl.pl_syscall_code == SYS_close);
+
+ ATF_REQUIRE(ptrace(PT_GET_SC_RET, wpid, (caddr_t)&psr,
+ sizeof(psr)) != -1);
+ ATF_REQUIRE(psr.sr_error == EBADF);
+
/* Disable syscall tracing and continue the child to let it exit. */
ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events,
sizeof(events)) == 0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 31, 2:23 AM (6 m, 2 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27399887
Default Alt Text
D20901.id59586.diff (7 KB)
Attached To
Mode
D20901: Add ptrace op PT_GET_SC_RET.
Attached
Detach File
Event Timeline
Log In to Comment