From: Oleg Nesterov <oleg@redhat.com>
To: Roland McGrath <roland@redhat.com>
Cc: Christoph Hellwig <hch@infradead.org>,
Ingo Molnar <mingo@elte.hu>,
linux-kernel@vger.kernel.org
Subject: [RFC PATCH 7/X] ptrace: mv task->parent ptrace_task->pt_tracer
Date: Mon, 25 May 2009 02:00:16 +0200 [thread overview]
Message-ID: <20090525000016.GA2239@redhat.com> (raw)
Move task_struct->parent into ptrace_task->pt_tracer and change the users
accordingly.
The next patches will add the helper to simplify/cleanup the usage of
->pt_tracer, and unify do_notify_parent/do_notify_parent_cldstop.
include/linux/sched.h | 8 +-------
include/linux/init_task.h | 1 -
include/linux/ptrace.h | 18 ++++++++++--------
include/linux/tracehook.h | 4 ++--
kernel/ptrace.c | 8 ++++----
kernel/exit.c | 18 +++++++-----------
kernel/signal.c | 24 +++++++++++++++---------
7 files changed, 39 insertions(+), 42 deletions(-)
--- PTRACE/include/linux/sched.h~7_MV_PARENT 2009-05-24 23:10:47.000000000 +0200
+++ PTRACE/include/linux/sched.h 2009-05-25 00:17:28.000000000 +0200
@@ -1186,13 +1186,7 @@ struct task_struct {
/* Canary value for the -fstack-protector gcc feature */
unsigned long stack_canary;
- /*
- * pointers to (original) parent process, youngest child, younger sibling,
- * older sibling, respectively. (p->father can be replaced with
- * p->real_parent->pid)
- */
- struct task_struct *real_parent; /* real parent process */
- struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */
+ struct task_struct *real_parent; /* parent process */
/*
* children/sibling forms the list of my natural children
*/
--- PTRACE/include/linux/init_task.h~7_MV_PARENT 2009-04-15 12:53:58.000000000 +0200
+++ PTRACE/include/linux/init_task.h 2009-05-25 01:30:35.000000000 +0200
@@ -139,7 +139,6 @@ extern struct cred init_cred;
.ptraced = LIST_HEAD_INIT(tsk.ptraced), \
.ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \
.real_parent = &tsk, \
- .parent = &tsk, \
.children = LIST_HEAD_INIT(tsk.children), \
.sibling = LIST_HEAD_INIT(tsk.sibling), \
.group_leader = &tsk, \
--- PTRACE/include/linux/ptrace.h~7_MV_PARENT 2009-05-24 23:38:10.000000000 +0200
+++ PTRACE/include/linux/ptrace.h 2009-05-25 00:27:38.000000000 +0200
@@ -76,7 +76,8 @@
#include <linux/sched.h> /* For struct task_struct. */
struct ptrace_task {
- unsigned long pt_flags;
+ unsigned long pt_flags;
+ struct task_struct *pt_tracer;
};
extern int alloc_ptrace_task(struct task_struct *child);
@@ -103,11 +104,6 @@ extern int __ptrace_may_access(struct ta
/* Returns true on success, false on denial. */
extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
-static inline int ptrace_reparented(struct task_struct *child)
-{
- return child->real_parent != child->parent;
-}
-
/**
* task_ptrace - return %PT_* flags that apply to a task
* @task: pointer to &task_struct in question
@@ -120,6 +116,12 @@ static inline int task_ptrace(struct tas
task->ptrace_task->pt_flags : 0;
}
+static inline int ptrace_reparented(struct task_struct *child)
+{
+ return unlikely(task_ptrace(child)) &&
+ child->ptrace_task->pt_tracer != child->real_parent;
+}
+
static inline void ptrace_unlink(struct task_struct *child)
{
if (unlikely(task_ptrace(child)))
@@ -164,10 +166,10 @@ static inline void ptrace_init_task(stru
{
INIT_LIST_HEAD(&child->ptrace_entry);
INIT_LIST_HEAD(&child->ptraced);
- child->parent = child->real_parent;
if (unlikely(child->ptrace_task) && task_ptrace(current))
- ptrace_link(child, task_ptrace(current), current->parent);
+ ptrace_link(child, task_ptrace(current),
+ current->ptrace_task->pt_tracer);
}
/**
--- PTRACE/include/linux/tracehook.h~7_MV_PARENT 2009-05-24 22:15:08.000000000 +0200
+++ PTRACE/include/linux/tracehook.h 2009-05-25 01:51:11.000000000 +0200
@@ -171,8 +171,8 @@ static inline int tracehook_unsafe_exec(
*/
static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk)
{
- if (task_ptrace(tsk) & PT_PTRACED)
- return rcu_dereference(tsk->parent);
+ if (tsk->ptrace_task)
+ return rcu_dereference(tsk->ptrace_task->pt_tracer);
return NULL;
}
--- PTRACE/kernel/ptrace.c~7_MV_PARENT 2009-05-25 00:03:45.000000000 +0200
+++ PTRACE/kernel/ptrace.c 2009-05-25 00:41:10.000000000 +0200
@@ -47,7 +47,7 @@ void ptrace_link(struct task_struct *chi
BUG_ON(!list_empty(&child->ptrace_entry));
list_add(&child->ptrace_entry, &tracer->ptraced);
- child->parent = tracer;
+ child->ptrace_task->pt_tracer = tracer;
}
/*
@@ -85,7 +85,7 @@ void __ptrace_unlink(struct task_struct
BUG_ON(!task_ptrace(child));
child->ptrace_task->pt_flags = 0;
- child->parent = child->real_parent;
+ child->ptrace_task->pt_tracer = NULL;
list_del_init(&child->ptrace_entry);
arch_ptrace_untrace(child);
@@ -108,7 +108,7 @@ int ptrace_check_attach(struct task_stru
* be changed by us so it's not changing right after this.
*/
read_lock(&tasklist_lock);
- if (task_ptrace(child) && child->parent == current) {
+ if (task_ptrace(child) && child->ptrace_task->pt_tracer == current) {
ret = 0;
/*
* child->sighand can't be NULL, release_task()
@@ -259,7 +259,7 @@ int ptrace_traceme(void)
write_lock_irq(&tasklist_lock);
/* Are we already being traced? */
if (!task_ptrace(current)) {
- ret = security_ptrace_traceme(current->parent);
+ ret = security_ptrace_traceme(current->real_parent);
/*
* Check PF_EXITING to ensure ->real_parent has not passed
* exit_ptrace(). Otherwise we don't report the error but
--- PTRACE/kernel/exit.c~7_MV_PARENT 2009-05-20 16:00:52.000000000 +0200
+++ PTRACE/kernel/exit.c 2009-05-25 00:49:27.000000000 +0200
@@ -336,7 +336,7 @@ static void reparent_to_kthreadd(void)
ptrace_unlink(current);
/* Reparent to init */
- current->real_parent = current->parent = kthreadd_task;
+ current->real_parent = kthreadd_task;
list_move_tail(¤t->sibling, ¤t->real_parent->children);
/* Set the exit signal to SIGCHLD so we signal init on exit */
@@ -780,10 +780,6 @@ static void forget_original_parent(struc
list_for_each_entry_safe(p, n, &father->children, sibling) {
p->real_parent = reaper;
- if (p->parent == father) {
- BUG_ON(task_ptrace(p));
- p->parent = p->real_parent;
- }
reparent_thread(father, p, &dead_children);
}
write_unlock_irq(&tasklist_lock);
@@ -1210,17 +1206,17 @@ static int wait_task_zombie(struct wait_
* p->signal fields, because they are only touched by
* __exit_signal, which runs with tasklist_lock
* write-locked anyway, and so is excluded here. We do
- * need to protect the access to p->parent->signal fields,
- * as other threads in the parent group can be right
- * here reaping other children at the same time.
+ * need to protect the access to p->real_parent->signal
+ * fields, as other threads in the parent group can be
+ * right here reaping other children at the same time.
*
* We use thread_group_cputime() to get times for the thread
* group, which consolidates times for all threads in the
* group including the group leader.
*/
thread_group_cputime(p, &cputime);
- spin_lock_irq(&p->parent->sighand->siglock);
- psig = p->parent->signal;
+ spin_lock_irq(&p->real_parent->sighand->siglock);
+ psig = p->real_parent->signal;
sig = p->signal;
psig->cutime =
cputime_add(psig->cutime,
@@ -1251,7 +1247,7 @@ static int wait_task_zombie(struct wait_
sig->oublock + sig->coublock;
task_io_accounting_add(&psig->ioac, &p->ioac);
task_io_accounting_add(&psig->ioac, &sig->ioac);
- spin_unlock_irq(&p->parent->sighand->siglock);
+ spin_unlock_irq(&p->real_parent->sighand->siglock);
}
/*
--- PTRACE/kernel/signal.c~7_MV_PARENT 2009-04-29 15:45:28.000000000 +0200
+++ PTRACE/kernel/signal.c 2009-05-25 01:22:58.000000000 +0200
@@ -1399,6 +1399,7 @@ int do_notify_parent(struct task_struct
{
struct siginfo info;
unsigned long flags;
+ struct task_struct *parent;
struct sighand_struct *psig;
int ret = sig;
@@ -1410,6 +1411,11 @@ int do_notify_parent(struct task_struct
BUG_ON(!task_ptrace(tsk) &&
(tsk->group_leader != tsk || !thread_group_empty(tsk)));
+ if (task_ptrace(tsk))
+ parent = tsk->ptrace_task->pt_tracer;
+ else
+ parent = tsk->real_parent;
+
info.si_signo = sig;
info.si_errno = 0;
/*
@@ -1425,7 +1431,7 @@ int do_notify_parent(struct task_struct
* correct to rely on this
*/
rcu_read_lock();
- info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+ info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns);
info.si_uid = __task_cred(tsk)->uid;
rcu_read_unlock();
@@ -1444,7 +1450,7 @@ int do_notify_parent(struct task_struct
info.si_status = tsk->exit_code >> 8;
}
- psig = tsk->parent->sighand;
+ psig = parent->sighand;
spin_lock_irqsave(&psig->siglock, flags);
if (!task_ptrace(tsk) && sig == SIGCHLD &&
(psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
@@ -1469,8 +1475,8 @@ int do_notify_parent(struct task_struct
sig = -1;
}
if (valid_signal(sig) && sig > 0)
- __group_send_sig_info(sig, &info, tsk->parent);
- __wake_up_parent(tsk, tsk->parent);
+ __group_send_sig_info(sig, &info, parent);
+ __wake_up_parent(tsk, parent);
spin_unlock_irqrestore(&psig->siglock, flags);
return ret;
@@ -1484,7 +1490,7 @@ static void do_notify_parent_cldstop(str
struct sighand_struct *sighand;
if (task_ptrace(tsk))
- parent = tsk->parent;
+ parent = tsk->ptrace_task->pt_tracer;
else {
tsk = tsk->group_leader;
parent = tsk->real_parent;
@@ -1496,7 +1502,7 @@ static void do_notify_parent_cldstop(str
* see comment in do_notify_parent() abot the following 3 lines
*/
rcu_read_lock();
- info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+ info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns);
info.si_uid = __task_cred(tsk)->uid;
rcu_read_unlock();
@@ -1544,7 +1550,7 @@ static inline int may_ptrace_stop(void)
* is safe to enter schedule().
*/
if (unlikely(current->mm->core_state) &&
- unlikely(current->mm == current->parent->mm))
+ unlikely(current->mm == current->ptrace_task->pt_tracer->mm))
return 0;
return 1;
@@ -1773,8 +1779,8 @@ static int ptrace_signal(int signr, sigi
info->si_signo = signr;
info->si_errno = 0;
info->si_code = SI_USER;
- info->si_pid = task_pid_vnr(current->parent);
- info->si_uid = task_uid(current->parent);
+ info->si_pid = task_pid_vnr(current->ptrace_task->pt_tracer);
+ info->si_uid = task_uid(current->ptrace_task->pt_tracer);
}
/* If the (new) signal is now blocked, requeue it. */
next reply other threads:[~2009-05-25 0:06 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-25 0:00 Oleg Nesterov [this message]
2009-05-25 21:59 ` [RFC PATCH 7/X] ptrace: mv task->parent ptrace_task->pt_tracer Oleg Nesterov
2009-05-25 22:39 ` [RFC PATCH 8/X] ptrace: introduce ptrace_tracer() helper Oleg Nesterov
2009-05-27 2:45 ` Roland McGrath
2009-05-27 21:45 ` Oleg Nesterov
2009-05-27 22:24 ` Roland McGrath
2009-05-27 2:11 ` [RFC PATCH 7/X] ptrace: mv task->parent ptrace_task->pt_tracer Roland McGrath
2009-05-27 22:41 ` Oleg Nesterov
2009-05-27 23:05 ` ptrace && task->exit_code Oleg Nesterov
2009-05-27 23:21 ` Roland McGrath
2009-05-29 19:06 ` Oleg Nesterov
2009-06-01 2:16 ` Roland McGrath
2009-05-27 23:07 ` [RFC PATCH 7/X] ptrace: mv task->parent ptrace_task->pt_tracer Roland McGrath
2009-05-27 23:59 ` Oleg Nesterov
2009-05-28 0:32 ` Roland McGrath
2009-05-28 2:54 ` Oleg Nesterov
2009-05-28 3:19 ` Roland McGrath
2009-05-28 3:35 ` Oleg Nesterov
2009-05-28 19:28 ` Roland McGrath
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090525000016.GA2239@redhat.com \
--to=oleg@redhat.com \
--cc=hch@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=roland@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.