diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2007-05-08 00:27:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 11:15:05 -0700 |
commit | d2d9433a4c84c9e7ed78d633fdbffb35d5afda17 (patch) | |
tree | 5a9fb2c9531bec148f21fc499d49493b5576e79c /kernel/irq | |
parent | c467a388ae9f236c039d4d0f4c4be07c7deebe97 (diff) |
kernel/irq/proc.c: unprotected iteration over the IRQ action list in name_unique()
setup_irq() releases a desc->lock before calling register_handler_proc(), so
the iteration over the IRQ action list is not protected.
(akpm: the check itself is still racy, but at least it probably won't oops
now).
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/proc.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 2db91eb54ad..ddde0ef9ccd 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -66,12 +66,19 @@ static int name_unique(unsigned int irq, struct irqaction *new_action) { struct irq_desc *desc = irq_desc + irq; struct irqaction *action; + unsigned long flags; + int ret = 1; - for (action = desc->action ; action; action = action->next) + spin_lock_irqsave(&desc->lock, flags); + for (action = desc->action ; action; action = action->next) { if ((action != new_action) && action->name && - !strcmp(new_action->name, action->name)) - return 0; - return 1; + !strcmp(new_action->name, action->name)) { + ret = 0; + break; + } + } + spin_unlock_irqrestore(&desc->lock, flags); + return ret; } void register_handler_proc(unsigned int irq, struct irqaction *action) |