On 07/24, Roland McGrath wrote:
>
> > For example, wait_consider_task(). Even some tracehooks, say,
> > tracehook_notify_death() need task_is_ptraced().
>
> Not "some", just that one, right?

Not just one. tracehook_tracer_task, tracehook_notify_jctl.

But,

> So these are all really the same one
> thing: ptrace interfering with normal parent wait/SIGCHLD.

yes, they are the same thing actually.

> So I'd do:
>
>       static inline bool tracehook_inhibit_wait(struct task_struct *task)
>       {
>               return task->utrace_flags && utrace_inhibit_wait(task);
>       }
>
> and then utrace_inhibit_wait can look at a bit we keep in struct utrace or
> something like that.  I think we might be able to get away with unlocked
> checks of that bit in wait, if we're sure that we'll do an extra
> wake_up_parent after detach or whatnot.

Yes, I thought about something like this too.

The problem is, I can't imagine all details now. And. I think it is better
to make the first working version as simple/small as possible.

So. For the first version of CONFIG_PTRACE_UTRACE I'd suggest to use
->ptrace to keep the single bit, PT_PTRACED (well, PT_PTRACE_CAP too).
All other PT_ bits should go into engine->data.

Also. Either we have to add a lot of #ifdef's into tracehook.h, or we
can add a single #ifdef into task_ptrace() (like your utrace-ptrace.patch
does). In the last case, do you think something like below makes sense?

is_task_ptraced() - means the same with or without utrace

task_ptrace() - returns 0 if CONFIG_UTRACE

Or we can start with reverting 5cb11446892833e50970fb2277a9f7563b0a8bd3
I regret about this patch now (and now I understand why you were not
very happy with this change ;). But this patch was needed for child-data
cleanups. However, I think we should forget about these cleanups for now.

In any case, we need some changes, and the patch should be sent separately,
before re-sending the updated version of utrace, afaics.

Oleg.

--- WAIT/include/linux/ptrace.h~1_IS_PTRACED    2009-06-19 01:12:47.000000000 
+0200
+++ WAIT/include/linux/ptrace.h 2009-08-03 21:49:19.000000000 +0200
@@ -120,6 +120,11 @@ static inline void ptrace_unlink(struct 
 int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
 int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
 
+static inline bool is_task_ptraced(struct task_struct *task)
+{
+       return task->ptrace != 0;
+}
+
 /**
  * task_ptrace - return %PT_* flags that apply to a task
  * @task:      pointer to &task_struct in question
--- WAIT/include/linux/tracehook.h~1_IS_PTRACED 2009-06-19 01:12:47.000000000 
+0200
+++ WAIT/include/linux/tracehook.h      2009-08-03 22:57:38.000000000 +0200
@@ -63,7 +63,7 @@ struct linux_binprm;
  */
 static inline int tracehook_expect_breakpoints(struct task_struct *task)
 {
-       return (task_ptrace(task) & PT_PTRACED) != 0;
+       return task_ptrace(task) != 0;
 }
 
 /*
@@ -73,7 +73,7 @@ static inline void ptrace_report_syscall
 {
        int ptrace = task_ptrace(current);
 
-       if (!(ptrace & PT_PTRACED))
+       if (!ptrace)
                return;
 
        ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
@@ -148,9 +148,8 @@ static inline void tracehook_report_sysc
 static inline int tracehook_unsafe_exec(struct task_struct *task)
 {
        int unsafe = 0;
-       int ptrace = task_ptrace(task);
-       if (ptrace & PT_PTRACED) {
-               if (ptrace & PT_PTRACE_CAP)
+       if (is_task_ptraced(task)) {
+               if (task->ptrace & PT_PTRACE_CAP)
                        unsafe |= LSM_UNSAFE_PTRACE_CAP;
                else
                        unsafe |= LSM_UNSAFE_PTRACE;
@@ -171,7 +170,7 @@ static inline int tracehook_unsafe_exec(
  */
 static inline struct task_struct *tracehook_tracer_task(struct task_struct 
*tsk)
 {
-       if (task_ptrace(tsk) & PT_PTRACED)
+       if (is_task_ptraced(tsk))
                return rcu_dereference(tsk->parent);
        return NULL;
 }
@@ -195,7 +194,7 @@ static inline void tracehook_report_exec
                                         struct pt_regs *regs)
 {
        if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
-           unlikely(task_ptrace(current) & PT_PTRACED))
+           unlikely(task_ptrace(current))
                send_sig(SIGTRAP, current, 0);
 }
 
@@ -379,7 +378,7 @@ static inline void tracehook_signal_hand
                                            const struct k_sigaction *ka,
                                            struct pt_regs *regs, int stepping)
 {
-       if (stepping)
+       if (task_ptrace(current) && stepping)
                ptrace_notify(SIGTRAP);
 }
 
@@ -396,7 +395,7 @@ static inline void tracehook_signal_hand
 static inline int tracehook_consider_ignored_signal(struct task_struct *task,
                                                    int sig)
 {
-       return (task_ptrace(task) & PT_PTRACED) != 0;
+       return task_ptrace(task) != 0;
 }
 
 /**
@@ -415,7 +414,7 @@ static inline int tracehook_consider_ign
 static inline int tracehook_consider_fatal_signal(struct task_struct *task,
                                                  int sig)
 {
-       return (task_ptrace(task) & PT_PTRACED) != 0;
+       return task_ptrace(task) != 0;
 }
 
 /**
@@ -478,7 +477,7 @@ static inline int tracehook_get_signal(s
  */
 static inline int tracehook_notify_jctl(int notify, int why)
 {
-       return notify || (current->ptrace & PT_PTRACED);
+       return notify || is_task_ptraced(current);
 }
 
 #define DEATH_REAP                     -1
@@ -502,7 +501,7 @@ static inline int tracehook_notify_death
                                         void **death_cookie, int group_dead)
 {
        if (task_detached(task))
-               return task->ptrace ? SIGCHLD : DEATH_REAP;
+               return is_task_ptraced(task) ? SIGCHLD : DEATH_REAP;
 
        /*
         * If something other than our normal parent is ptracing us, then
@@ -512,7 +511,7 @@ static inline int tracehook_notify_death
        if (thread_group_empty(task) && !ptrace_reparented(task))
                return task->exit_signal;
 
-       return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER;
+       return is_task_ptraced(task) ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER;
 }
 
 /**
--- WAIT/kernel/ptrace.c~1_IS_PTRACED   2009-07-01 20:52:58.000000000 +0200
+++ WAIT/kernel/ptrace.c        2009-08-03 22:56:36.000000000 +0200
@@ -95,7 +95,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 ((child->ptrace & PT_PTRACED) && child->parent == current) {
+       if (child->ptrace && child->parent == current) {
                ret = 0;
                /*
                 * child->sighand can't be NULL, release_task()
--- WAIT/kernel/exit.c~1_IS_PTRACED     2009-07-02 20:19:55.000000000 +0200
+++ WAIT/kernel/exit.c  2009-08-03 22:41:19.000000000 +0200
@@ -754,7 +754,7 @@ static void reparent_leader(struct task_
        p->exit_signal = SIGCHLD;
 
        /* If it has exited notify the new parent about this child's death. */
-       if (!task_ptrace(p) &&
+       if (!is_task_ptraced(p) &&
            p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
                do_notify_parent(p, p->exit_signal);
                if (task_detached(p)) {
@@ -781,7 +781,7 @@ static void forget_original_parent(struc
                do {
                        t->real_parent = reaper;
                        if (t->parent == father) {
-                               BUG_ON(task_ptrace(t));
+                               BUG_ON(is_task_ptraced(t));
                                t->parent = t->real_parent;
                        }
                        if (t->pdeath_signal)
@@ -1492,7 +1492,7 @@ static int wait_consider_task(struct wai
                return 0;
        }
 
-       if (likely(!ptrace) && unlikely(task_ptrace(p))) {
+       if (likely(!ptrace) && unlikely(is_task_ptraced(p))) {
                /*
                 * This child is hidden by ptrace.
                 * We aren't allowed to see it now, but eventually we will.
--- WAIT/kernel/signal.c~1_IS_PTRACED   2009-08-01 02:21:27.000000000 +0200
+++ WAIT/kernel/signal.c        2009-08-03 22:42:20.000000000 +0200
@@ -1398,7 +1398,7 @@ int do_notify_parent(struct task_struct 
        /* do_notify_parent_cldstop should have been called instead.  */
        BUG_ON(task_is_stopped_or_traced(tsk));
 
-       BUG_ON(!task_ptrace(tsk) &&
+       BUG_ON(!is_task_ptraced(tsk) &&
               (tsk->group_leader != tsk || !thread_group_empty(tsk)));
 
        info.si_signo = sig;
@@ -1437,7 +1437,7 @@ int do_notify_parent(struct task_struct 
 
        psig = tsk->parent->sighand;
        spin_lock_irqsave(&psig->siglock, flags);
-       if (!task_ptrace(tsk) && sig == SIGCHLD &&
+       if (!is_task_ptraced(tsk) && sig == SIGCHLD &&
            (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
             (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
                /*
@@ -1474,7 +1474,7 @@ static void do_notify_parent_cldstop(str
        struct task_struct *parent;
        struct sighand_struct *sighand;
 
-       if (task_ptrace(tsk))
+       if (is_task_ptraced(tsk))
                parent = tsk->parent;
        else {
                tsk = tsk->group_leader;

Reply via email to