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 *);