From: Rusty Russell We can't compare waitpid() result with stop->k->tgid, since the thread will be gone by then (thanks to Andrey Borzenkov and CONFIG_DEBUG_PAGEALLOC! --- kernel/kthread.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff -puN kernel/kthread.c~kthread-use-after-free-fix kernel/kthread.c --- 25/kernel/kthread.c~kthread-use-after-free-fix 2004-02-04 22:26:45.000000000 -0800 +++ 25-akpm/kernel/kthread.c 2004-02-04 22:26:45.000000000 -0800 @@ -96,7 +96,7 @@ static void adopt_kthread(struct task_st static void keventd_stop_kthread(void *_stop) { struct kthread_stop_info *stop = _stop; - int status; + int status, pid; sigset_t blocked; struct k_sigaction sa; @@ -108,11 +108,14 @@ static void keventd_stop_kthread(void *_ allow_signal(SIGCHLD); adopt_kthread(stop->k); + /* Grab pid now: after waitpid(), stop->k is invalid. */ + pid = stop->k->tgid; + /* All signals are blocked, hence the force. */ force_sig(SIGTERM, stop->k); /* Other threads might exit: if we ask for one pid that * returns -ERESTARTSYS. */ - while (waitpid(-1, &status, __WALL) != stop->k->tgid) + while (waitpid(-1, &status, __WALL) != pid) flush_signals(current); stop->result = -((status >> 8) & 0xFF); complete(&stop->done); _