[HACK] utrace: "fix" utrace_resume()->finish_resume_report() logic

Oleg Nesterov oleg at redhat.com
Mon Nov 16 16:52:15 UTC 2009


In short, it is just wrong to call finish_resume_report() in utrace_resume()
without reporting loop, because utrace never clears TIF_NOTIFY_RESUME. It is
very possible we enter utrace_resume() with utrace->resume == UTRACE_RESUME,
in this case finish_resume_report() does user_disable_single_step(). And if
TIF_SINGLESTEP was previously set by utrace_get_signal() which noticed
->resume < UTRACE_RESUME we lost: engine can't re-assert the stepping.

IOW. Just one example. The tracee reports the signal and sleeps in
utrace_get_signal()->finish_resume_report().

Suppose that the tracee has TIF_NOTIFY_RESUME bit set. A lot of reasons
why this can happen.

The tracer wakes up the tracee via utrace_control(UTRACE_SINGLESTEP).

The tracee resumes, calls utrace_get_signal_again(), notices
utrace->resume < UTRACE_RESUME, resets utrace->resume, and does
finish_resume_report()->enable_step() correctly.

But, since TIF_NOTIFY_RESUME is set, the tracee will call utrace_resume()
before return to user-mode, and the next finish_resume_report() from
utrace_resume() clears TIF_SINGLESTEP.


Of course, this is just the temporary hack, to do the testing right now.
I still do not understand the new code in details, need to read it
carefully but didn't have the time yet :/

---

 kernel/utrace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- UTRACE-PTRACE/kernel/utrace.c~UTRACE_HACK_RESUME	2009-11-16 17:02:11.000000000 +0100
+++ UTRACE-PTRACE/kernel/utrace.c	2009-11-16 17:28:10.000000000 +0100
@@ -1871,7 +1871,7 @@ void utrace_resume(struct task_struct *t
 	 */
 	report.action = start_report(utrace);
 
-	if (report.action == UTRACE_REPORT &&
+	if (1 && //report.action == UTRACE_REPORT &&
 	    likely(task->utrace_flags & UTRACE_EVENT(QUIESCE))) {
 		/*
 		 * Do a simple reporting pass, with no specific




More information about the utrace-devel mailing list