Commit 325d6f55 authored by Haavard Skinnemoen's avatar Haavard Skinnemoen

avr32: Fix OCD refcounting bug

Iff the parent has TIF_DEBUG set, _and_ clone_flags includes
CLONE_PTRACE we should set the TIF_DEBUG flag for the child and
increment the ocd refcount. Otherwise, the TIF_DEBUG flag must be
unset.

Currently, the child inherits TIF_DEBUG from the parent before
copy_thread is called, so TIF_DEBUG may be already be set before we
determine whether the child is supposed to inherit debugging
capabilities from the parent or not. This means that ocd_enable()
won't increment the refcount, because TIF_DEBUG is already set, and
that TIF_DEBUG will be set for processes that aren't being debugged.

This leads to a refcounting asymmetry, which may show up as

------------[ cut here ]------------
Badness at arch/avr32/kernel/ocd.c:73
PC is at ocd_disable+0x34/0x60
LR is at put_lock_stats+0xa/0x20

as reported by David Brownell. Happens when strace'ing a process that
forks a new child process, e.g. "strace mount -tjffs2 mtd1 /mnt", and
subsequently killing the child process (e.g. "umount /mnt".)
Signed-off-by: default avatarHaavard Skinnemoen <hskinnemoen@atmel.com>
parent d45ad062
...@@ -348,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -348,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.ksp = (unsigned long)childregs;
p->thread.cpu_context.pc = (unsigned long)ret_from_fork; p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
clear_tsk_thread_flag(p, TIF_DEBUG);
if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
ocd_enable(p); ocd_enable(p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment