From 5861bbfcc10fc0358abf52c7d22850c8d180f0b0 Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland@redhat.com>
Date: Thu, 7 Aug 2008 16:55:03 -0700
Subject: [PATCH] tracehook: fix CLONE_PTRACE

In the change in commit 09a05394fe2448a4139b014936330af23fa7ec83, I
overlooked two nits in the logic and this broke using CLONE_PTRACE
when PTRACE_O_TRACE* are not being used.

A parent that is itself traced at all but not using PTRACE_O_TRACE*,
using CLONE_PTRACE would have its new child fail to be traced.

A parent that is not itself traced at all that uses CLONE_PTRACE
(which should be a no-op in this case) would confuse the bookkeeping
and lead to a crash at exit time.

This restores the missing checks and fixes both failure modes.

Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Roland McGrath <roland@redhat.com>
---
 include/linux/ptrace.h    | 2 +-
 include/linux/tracehook.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index fd31756e1a0..ea7416c901d 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -172,7 +172,7 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace)
 	child->ptrace = 0;
 	if (unlikely(ptrace)) {
 		child->ptrace = current->ptrace;
-		__ptrace_link(child, current->parent);
+		ptrace_link(child, current->parent);
 	}
 }
 
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index ab3ef7aefa9..b48d8196957 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -280,7 +280,7 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
 					  unsigned long clone_flags,
 					  pid_t pid, struct task_struct *child)
 {
-	if (unlikely(trace)) {
+	if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) {
 		/*
 		 * The child starts up with an immediate SIGSTOP.
 		 */
-- 
2.41.3