PT_CONTINUE: undo transparent attach consequences

PR:	287050
Reported and tested by:	Paul Floyd <pjfloyd@wanadoo.fr>
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D50556
This commit is contained in:
Konstantin Belousov
2025-05-28 00:09:18 +03:00
parent def0c056d3
commit 9997693427
+22
View File
@@ -39,6 +39,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mutex.h> #include <sys/mutex.h>
#include <sys/reg.h> #include <sys/reg.h>
#include <sys/sleepqueue.h>
#include <sys/syscallsubr.h> #include <sys/syscallsubr.h>
#include <sys/sysent.h> #include <sys/sysent.h>
#include <sys/sysproto.h> #include <sys/sysproto.h>
@@ -1346,6 +1347,27 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (data == SIGKILL) if (data == SIGKILL)
proc_wkilled(p); proc_wkilled(p);
/*
* If the PT_CONTINUE-like operation is attempted on
* the thread on sleepq, this is possible only after
* the transparent PT_ATTACH. In this case, if the
* caller modified the thread state, e.g. by writing
* register file or specifying the pc, make the thread
* xstopped by waking it up.
*/
if ((td2->td_dbgflags & TDB_USERWR) != 0) {
if (pt_attach_transparent) {
thread_lock(td2);
if (TD_ON_SLEEPQ(td2) &&
(td2->td_flags & TDF_SINTR) != 0) {
sleepq_abort(td2, EINTR);
} else {
thread_unlock(td2);
}
}
td2->td_dbgflags &= ~TDB_USERWR;
}
/* /*
* Unsuspend all threads. To leave a thread * Unsuspend all threads. To leave a thread
* suspended, use PT_SUSPEND to suspend it before * suspended, use PT_SUSPEND to suspend it before