This patch fixes the leak in uproc refcount when a tracing thread does
defer_registration.
    
When threads queue defer_registration, uprobes was leaking uproc
refcount. If a tracing process requested a [un]register operation that
was defered, then subsequent removal of all probes would still keep the
uprobes engine active till the thread dies.

Jim Keniston's observation on uprobes lifetime made me figure out an
error in defer_registration patch that I sent earlier.

Signed-off-by: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
---
 kernel/uprobes_core.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/kernel/uprobes_core.c b/kernel/uprobes_core.c
index d784d4a..27c2977 100644
--- a/kernel/uprobes_core.c
+++ b/kernel/uprobes_core.c
@@ -945,10 +945,8 @@ int register_uprobe(struct uprobe *u)
                         */
                        BUG_ON(utask->state != UPTASK_SSTEP);
                        if (task_is_stopped_or_traced(utask->tsk)) {
-                               put_pid(p);
                                ret =  defer_registration(u, 1, utask);
-                               up_write(&uproc->rwsem);
-                               return ret;
+                               goto fail_uproc;
                        }
                }
        } else {
@@ -1127,10 +1125,8 @@ void unregister_uprobe(struct uprobe *u)
                /* See comment in register_uprobe(). */
                BUG_ON(utask->state != UPTASK_SSTEP);
                if (task_is_stopped_or_traced(utask->tsk)) {
-                       put_pid(p);
                        (void) defer_registration(u, 0, utask);
-                       up_write(&uproc->rwsem);
-                       return;
+                       goto done;
                }
        }
        uk = (struct uprobe_kimg *)u->kdata;

Reply via email to