linux-stable/kernel/irq
Yunfeng Ye 991b3458da genirq: Prevent NULL pointer dereference in resend_irqs()
commit eddf3e9c7c upstream.

The following crash was observed:

  Unable to handle kernel NULL pointer dereference at 0000000000000158
  Internal error: Oops: 96000004 [#1] SMP
  pc : resend_irqs+0x68/0xb0
  lr : resend_irqs+0x64/0xb0
  ...
  Call trace:
   resend_irqs+0x68/0xb0
   tasklet_action_common.isra.6+0x84/0x138
   tasklet_action+0x2c/0x38
   __do_softirq+0x120/0x324
   run_ksoftirqd+0x44/0x60
   smpboot_thread_fn+0x1ac/0x1e8
   kthread+0x134/0x138
   ret_from_fork+0x10/0x18

The reason for this is that the interrupt resend mechanism happens in soft
interrupt context, which is a asynchronous mechanism versus other
operations on interrupts. free_irq() does not take resend handling into
account. Thus, the irq descriptor might be already freed before the resend
tasklet is executed. resend_irqs() does not check the return value of the
interrupt descriptor lookup and derefences the return value
unconditionally.

  1):
  __setup_irq
    irq_startup
      check_irq_resend  // activate softirq to handle resend irq
  2):
  irq_domain_free_irqs
    irq_free_descs
      free_desc
        call_rcu(&desc->rcu, delayed_free_desc)
  3):
  __do_softirq
    tasklet_action
      resend_irqs
        desc = irq_to_desc(irq)
        desc->handle_irq(desc)  // desc is NULL --> Ooops

Fix this by adding a NULL pointer check in resend_irqs() before derefencing
the irq descriptor.

Fixes: a4633adcdb ("[PATCH] genirq: add genirq sw IRQ-retrigger")
Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/1630ae13-5c8e-901e-de09-e740b6a426a7@huawei.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-09-19 09:09:34 +02:00
..
affinity.c genirq/affinity: Spread IRQs to all available NUMA nodes 2019-02-12 19:46:57 +01:00
autoprobe.c genirq: Delay deactivation in free_irq() 2019-07-21 09:03:12 +02:00
chip.c genirq: Delay deactivation in free_irq() 2019-07-21 09:03:12 +02:00
cpuhotplug.c genirq: Delay deactivation in free_irq() 2019-07-21 09:03:12 +02:00
debug.h Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/pmladek/printk 2018-02-01 13:36:15 -08:00
debugfs.c genirq/debugfs: Add missing IRQCHIP_SUPPORTS_LEVEL_MSI debug 2018-06-22 14:22:00 +02:00
devres.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
dummychip.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
generic-chip.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
handle.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
internals.h genirq: Add optional hardware synchronization for shutdown 2019-07-21 09:03:13 +02:00
ipi.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
irq_sim.c genirq/irq_sim: Remove the license boilerplate 2018-04-26 22:26:39 +02:00
irqdesc.c genirq: Properly pair kobject_del() with kobject_add() 2019-08-29 08:28:57 +02:00
irqdomain.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
Kconfig genirq/irqchip: Remove MULTI_IRQ_HANDLER as it's now obselete 2018-08-03 12:14:10 +02:00
Makefile Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:33:11 -08:00
manage.c genirq: Add optional hardware synchronization for shutdown 2019-07-21 09:03:13 +02:00
matrix.c genirq/matrix: Improve target CPU selection for managed interrupts. 2019-03-05 17:58:45 +01:00
migration.c genirq/migration: Avoid out of line call if pending is not set 2018-06-06 15:18:20 +02:00
msi.c genirq/msi: Allow level-triggered MSIs to be exposed by MSI providers 2018-05-13 15:58:59 +02:00
pm.c genirq: Add missing SPDX identifiers 2018-03-20 14:23:28 +01:00
proc.c genirq: Speedup show_interrupts() 2018-06-22 14:22:58 +02:00
resend.c genirq: Prevent NULL pointer dereference in resend_irqs() 2019-09-19 09:09:34 +02:00
settings.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
spurious.c genirq: Cleanup top of file comments 2018-03-20 14:23:27 +01:00
timings.c genirq: Remove license boilerplate/references 2018-03-20 14:23:28 +01:00