[PATCH 39] make sure PTRACE_SYSCALL reports SYSCALL_EXIT

Oleg Nesterov oleg at redhat.com
Tue Sep 15 18:49:03 UTC 2009


Another test-case:

	#define WEVENT(s) ((s & 0xFF0000) >> 16)

	int main(void)
	{
		int pid, stat;

		pid = fork();
		if (!pid) {
			assert(0 == ptrace(PTRACE_TRACEME, 0,0,0));
			kill(getpid(), SIGSTOP);

			execl("/bin/false", "true", NULL);

			assert(0);
		}

		assert(wait(&stat) == pid);
		assert(WIFSTOPPED(stat) && WSTOPSIG(stat) == SIGSTOP);

		assert(0 == ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACEEXEC));

		for (;;) {
			assert(0 == ptrace(PTRACE_CONT, pid, 0, 0));
			assert(waitpid(pid, &stat, __WALL) == pid);

			if (WEVENT(stat) == PTRACE_EVENT_EXEC)
				break;

		}

		kill(pid, SIGINT);
		assert(0 == ptrace(PTRACE_SYSCALL, pid, 0, 0));
		assert(waitpid(pid, &stat, __WALL) == pid);

		// must see SYSCALL_EXIT first,
		assert(WIFSTOPPED(stat) && WSTOPSIG(stat) == SIGTRAP);

		assert(0 == ptrace(PTRACE_SYSCALL, pid, 0, 0));
		assert(waitpid(pid, &stat, __WALL) == pid);

		// then SIGINT
		assert(WIFSTOPPED(stat) && WSTOPSIG(stat) == SIGINT);

		return 0;
	}

If the tracee enters PTRACE_EVENT_EXEC stop without TIF_SYSCALL_TRACE
and then the tracer does ptrace(PTRACE_SYSCALL), we should report
SYSCALL_EXIT event.

---

 kernel/ptrace.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

--- PU/kernel/ptrace.c~39_FIX_EXEC_SYSCALL	2009-09-15 18:36:40.000000000 +0200
+++ PU/kernel/ptrace.c	2009-09-15 19:47:50.000000000 +0200
@@ -335,6 +335,17 @@ static u32 ptrace_report_syscall_exit(en
 	return UTRACE_STOP;
 }
 
+static void ptrace_resume_ck_syscall(struct utrace_engine *engine,
+				struct task_struct *tracee, long data)
+{
+	struct ptrace_context *context = ptrace_context(engine);
+
+	if (context->options & PTRACE_O_TRACE_SYSCALL) {
+		if (ev_empty(context))
+			push_syscall_event(context);
+	}
+}
+
 static u32 ptrace_report_exec(enum utrace_resume_action action,
 			      struct utrace_engine *engine,
 			      struct task_struct *task,
@@ -354,6 +365,7 @@ static u32 ptrace_report_exec(enum utrac
 	}
 
 	ev = ev_push(context);
+	ev->ev_resume = ptrace_resume_ck_syscall;
 	ev->ev_code = (PTRACE_EVENT_EXEC << 8) | SIGTRAP;
 
 	return UTRACE_STOP;




More information about the utrace-devel mailing list