lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 26 Nov 2010 11:49:23 +0100
From:	Tejun Heo <tj@...nel.org>
To:	roland@...hat.com, oleg@...hat.com, linux-kernel@...r.kernel.org,
	torvalds@...ux-foundation.org, akpm@...ux-foundation.org,
	"rjw@...k.plpavel"@ucw.cz
Cc:	Tejun Heo <tj@...nel.org>
Subject: [PATCH 08/14] ptrace: make do_signal_stop() use ptrace_stop() if the task is being ptraced

A ptraced task would still stop at do_signal_stop() when it's stopping
for stop signals and do_signal_stop() behaves the same whether the
task is ptraced or not.  However, in addition to stopping,
ptrace_stop() also does ptrace specific stuff like calling
architecture specific callbacks, so this behavior makes the code more
fragile and difficult to understand.

This patch makes do_signal_stop() test whether the task is ptraced and
use ptrace_stop() if so.  This renders tracehook_notify_jctl() rather
pointless as the ptrace notification is now handled by ptrace_stop()
regardless of the return value from the tracehook.  It probably is a
good idea to update it.

This doesn't solve the whole problem as tasks already in stopped state
would stay in the regular stop when ptrace attached.  That part will
be handled by the next patch.

Signed-off-by: Tejun Heo <tj@...nel.org>
Cc: Oleg Nesterov <oleg@...hat.com>
Cc: Roland McGrath <roland@...hat.com>
---
 kernel/signal.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 3b3e69c..6d78da6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1788,10 +1788,8 @@ static int do_signal_stop(int signr)
 	 * we test GROUP_STOP_PENDING again.  If SIGCONT or SIGKILL
 	 * comes in between, it would be clear.
 	 */
-	if (!(current->group_stop & GROUP_STOP_PENDING)) {
-		spin_unlock_irq(&current->sighand->siglock);
-		goto out;
-	}
+	if (!(current->group_stop & GROUP_STOP_PENDING))
+		goto out_unlock;
 
 	if (consume_group_stop())
 		sig->flags = SIGNAL_STOP_STOPPED;
@@ -1800,17 +1798,24 @@ static int do_signal_stop(int signr)
 	current->group_stop &= ~GROUP_STOP_PENDING;
 	__set_current_state(TASK_STOPPED);
 
-	spin_unlock_irq(&current->sighand->siglock);
+	if (likely(!task_ptrace(current))) {
+		spin_unlock_irq(&current->sighand->siglock);
 
-	if (notify) {
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(current, notify);
-		read_unlock(&tasklist_lock);
-	}
+		if (notify) {
+			read_lock(&tasklist_lock);
+			do_notify_parent_cldstop(current, notify);
+			read_unlock(&tasklist_lock);
+		}
+
+		/* Now we don't run again until woken by SIGCONT or SIGKILL */
+		schedule();
+
+		spin_lock_irq(&current->sighand->siglock);
+	} else
+		ptrace_stop(current->exit_code, CLD_STOPPED, 0, NULL);
+out_unlock:
+	spin_unlock_irq(&current->sighand->siglock);
 
-	/* Now we don't run again until woken by SIGCONT or SIGKILL */
-	schedule();
-out:
 	tracehook_finish_jctl();
 	current->exit_code = 0;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ