Commit cc8c3b78433222e5dbc1fdfcfdde29e1743f181a
1 parent
0b1adaa031
genirq: Protect access to irq_desc->action in can_request_irq()
can_request_irq() accesses and dereferences irq_desc->action w/o holding irq_desc->lock. So action can be freed on another CPU before it's dereferenced. Unlikely, but ... Protect it with desc->lock. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Showing 1 changed file with 4 additions and 0 deletions Side-by-side Diff
kernel/irq/manage.c
... | ... | @@ -382,6 +382,7 @@ |
382 | 382 | { |
383 | 383 | struct irq_desc *desc = irq_to_desc(irq); |
384 | 384 | struct irqaction *action; |
385 | + unsigned long flags; | |
385 | 386 | |
386 | 387 | if (!desc) |
387 | 388 | return 0; |
388 | 389 | |
... | ... | @@ -389,10 +390,13 @@ |
389 | 390 | if (desc->status & IRQ_NOREQUEST) |
390 | 391 | return 0; |
391 | 392 | |
393 | + raw_spin_lock_irqsave(&desc->lock, flags); | |
392 | 394 | action = desc->action; |
393 | 395 | if (action) |
394 | 396 | if (irqflags & action->flags & IRQF_SHARED) |
395 | 397 | action = NULL; |
398 | + | |
399 | + raw_spin_unlock_irqrestore(&desc->lock, flags); | |
396 | 400 | |
397 | 401 | return !action; |
398 | 402 | } |