Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ptrace_attach: fix possible deadlock schenario with irqs

Eric Biederman points out that we can't take the task_lock while holding
tasklist_lock for writing, because another CPU that holds the task lock
might take an interrupt that then tries to take tasklist_lock for writing.

Which would be a nasty deadlock, with one CPU spinning forever in an
interrupt handler (although admittedly you need to really work at
triggering it ;)

Since the ptrace_attach() code is special and very unusual, just make it
be extra careful, and use trylock+repeat to avoid the possible deadlock.

Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+19 -1
+19 -1
kernel/ptrace.c
··· 155 155 if (task->tgid == current->tgid) 156 156 goto out; 157 157 158 - write_lock_irq(&tasklist_lock); 158 + repeat: 159 + /* 160 + * Nasty, nasty. 161 + * 162 + * We want to hold both the task-lock and the 163 + * tasklist_lock for writing at the same time. 164 + * But that's against the rules (tasklist_lock 165 + * is taken for reading by interrupts on other 166 + * cpu's that may have task_lock). 167 + */ 159 168 task_lock(task); 169 + local_irq_disable(); 170 + if (!write_trylock(&tasklist_lock)) { 171 + local_irq_enable(); 172 + task_unlock(task); 173 + do { 174 + cpu_relax(); 175 + } while (!write_can_lock(&tasklist_lock)); 176 + goto repeat; 177 + } 160 178 161 179 /* the same process cannot be attached many times */ 162 180 if (task->ptrace & PT_PTRACED)