Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2075

kernel-2.6.18-238.el5.src.rpm

From: Jerome Marchand <jmarchan@redhat.com>
Date: Mon, 20 Oct 2008 16:08:34 +0200
Subject: [misc] ptrace: fix exec report
Message-id: 48FC90E2.60004@redhat.com
O-Subject: [RHEL5 Patch] ptrace: fix exec report
Bugzilla: 455060

Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=455060

Description:
A traced process executing execve() is stopped by a SIGTRAP. If the
tracer uses ptrace(PTRACE_KILL...) to kill it, the tracee continues
his execution instead of beeing killed.
The tracee is not stopped by a real SIGTRAP signal but just put
SIGTRAP in current->exit_code and notifies the tracer. The problem is
that ptrace signal injection does not work outside the context of a
real signal and the tracee never get the SIGKILL signal.

Solution:
Send a real SIGTRAP to stop the tracee if PTRACE_O_TRACEEXEC option is
not set. That means that a process stopped in execve() when
PTRACE_O_TRACEEXEC is set, is still not killable by PTRACE_KILL. If
PTRACE_O_TRACEEXEC is not set, we can send any kind of signal to the
tracee (including of course SIGKILL).
That behaviour matchs upstream.

Brew build:
https://brewweb.devel.redhat.com/taskinfo?taskID=1517658

Test status:
Build and test on i686.

Regards,
Jerome

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 2c363b8..256ac34 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1943,9 +1943,16 @@ ptrace_report_exec(struct utrace_attached_engine *engine,
 	if (unlikely(state == NULL))
 		return UTRACE_ACTION_RESUME;
 
-	return ptrace_event(engine, tsk, state,
-			    (state->options & PTRACE_O_TRACEEXEC)
-			    ? PTRACE_EVENT_EXEC : 0);
+	if (state->options & PTRACE_O_TRACEEXEC)
+		return ptrace_event(engine, tsk, state, PTRACE_EVENT_EXEC);
+
+	/*
+	 * Without PTRACE_O_TRACEEXEC, this is not a stop in the
+	 * ptrace_notify() style.  Instead, it's a regular signal.
+	 * The difference is in where the real stop takes place and
+	 * what ptrace can do with tsk->exit_code there.
+	 */
+	send_sig(SIGTRAP, tsk, 0);
 }
 
 static u32