On 11/16, Oleg Nesterov wrote:
>
> And I didn't check "make xcheck", I guess it still crashes the kernel.

Yes it does. I am almost sure the bug should be trivial, but
somehow can't find find it. Just fyi, to ensure this is connected
to utrace-indirect I applied the hack below and the bug goes away.

OK. Tomorrow I will just read utrace.c trying to understand the
details of the new code, perhaps I will notice something.

Oleg.

--- UTRACE-PTRACE/kernel/fork.c~XXX_CRASH       2009-11-16 20:26:23.000000000 
+0100
+++ UTRACE-PTRACE/kernel/fork.c 2009-11-16 21:18:57.000000000 +0100
@@ -970,6 +970,8 @@ static void posix_cpu_timers_init(struct
  * parts of the process environment (as per the clone
  * flags). The actual kick-off is left to the caller.
  */
+bool utrace_task_alloc(struct task_struct *task);
+
 static struct task_struct *copy_process(unsigned long clone_flags,
                                        unsigned long stack_start,
                                        struct pt_regs *regs,
@@ -1227,6 +1229,10 @@ static struct task_struct *copy_process(
        cgroup_fork_callbacks(p);
        cgroup_callbacks_done = 1;
 
+       p->utrace = NULL;
+       if (!utrace_task_alloc(p))
+               WARN_ON(1);
+
        /* Need tasklist lock for parent etc handling! */
        write_lock_irq(&tasklist_lock);
 
--- UTRACE-PTRACE/kernel/utrace.c~XXX_CRASH     2009-11-16 20:31:38.000000000 
+0100
+++ UTRACE-PTRACE/kernel/utrace.c       2009-11-16 21:19:26.000000000 +0100
@@ -87,9 +87,9 @@ module_init(utrace_init);
  *
  * This returns false only in case of a memory allocation failure.
  */
-static bool utrace_task_alloc(struct task_struct *task)
+bool utrace_task_alloc(struct task_struct *task)
 {
-       struct utrace *utrace = kmem_cache_zalloc(utrace_cachep, GFP_KERNEL);
+       struct utrace *utrace = kzalloc(sizeof(struct utrace), GFP_KERNEL);
        if (unlikely(!utrace))
                return false;
        spin_lock_init(&utrace->lock);
@@ -108,7 +108,7 @@ static bool utrace_task_alloc(struct tas
        }
        task_unlock(task);
        if (unlikely(task->utrace != utrace))
-               kmem_cache_free(utrace_cachep, utrace);
+               kfree(utrace);
        return true;
 }
 
@@ -118,7 +118,7 @@ static bool utrace_task_alloc(struct tas
  */
 void utrace_free_task(struct task_struct *task)
 {
-       kmem_cache_free(utrace_cachep, task->utrace);
+       kfree(task->utrace);
 }
 
 /*
@@ -286,6 +286,8 @@ struct utrace_engine *utrace_attach_task
        struct utrace_engine *engine;
        int ret;
 
+       WARN_ON(!utrace);
+
        if (!(flags & UTRACE_ATTACH_CREATE)) {
                if (unlikely(!utrace))
                        return ERR_PTR(-ENOENT);
--- UTRACE-PTRACE/include/linux/utrace.h~XXX_CRASH      2009-11-16 
01:06:34.000000000 +0100
+++ UTRACE-PTRACE/include/linux/utrace.h        2009-11-16 20:50:38.000000000 
+0100
@@ -163,7 +163,7 @@ static inline struct utrace *task_utrace
 static inline void utrace_init_task(struct task_struct *task)
 {
        task->utrace_flags = 0;
-       task->utrace = NULL;
+       WARN_ON(!task->utrace);
 }
 
 void utrace_release_task(struct task_struct *);

Reply via email to