android_kernel_samsung_a7y1.../kernel/irq
Yunfeng Ye bea6938d49 genirq: Prevent NULL pointer dereference in resend_irqs()
commit eddf3e9c7c7e4d0707c68d1bb22cc6ec8aef7d4a 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: a4633adcdbc1 ("[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>
2020-04-06 21:35:35 +02:00
..
autoprobe.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
chip.c genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() 2020-04-06 15:08:26 +02:00
cpuhotplug.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
debug.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
devres.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
dummychip.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
generic-chip.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
handle.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
internals.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
irqdesc.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
irqdomain.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
Kconfig A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
Makefile A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
manage.c genirq: Prevent use-after-free and work list corruption 2020-04-06 16:43:02 +02:00
migration.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
msi.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
pm.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
proc.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
resend.c genirq: Prevent NULL pointer dereference in resend_irqs() 2020-04-06 21:35:35 +02:00
settings.h A750FXXU4CTBC 2020-03-27 21:51:54 +05:30
spurious.c A750FXXU4CTBC 2020-03-27 21:51:54 +05:30