diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-16 21:28:54 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-16 21:28:54 +0200 |
commit | b498eaeb80bda9693a5158b3c13924f71aae7afa (patch) | |
tree | 93129f16791a5fa0e6cead834c65798e2d052fb0 | |
parent | 2f2387e5223e1aa80876261d423f8ce7242ebe89 (diff) | |
download | queue-3.18-b498eaeb80bda9693a5158b3c13924f71aae7afa.tar.gz |
another
-rw-r--r-- | genirq-prevent-null-pointer-dereference-in-resend_irqs.patch | 76 | ||||
-rw-r--r-- | series | 1 |
2 files changed, 77 insertions, 0 deletions
diff --git a/genirq-prevent-null-pointer-dereference-in-resend_irqs.patch b/genirq-prevent-null-pointer-dereference-in-resend_irqs.patch new file mode 100644 index 0000000..1e1116c --- /dev/null +++ b/genirq-prevent-null-pointer-dereference-in-resend_irqs.patch @@ -0,0 +1,76 @@ +From eddf3e9c7c7e4d0707c68d1bb22cc6ec8aef7d4a Mon Sep 17 00:00:00 2001 +From: Yunfeng Ye <yeyunfeng@huawei.com> +Date: Wed, 4 Sep 2019 20:46:25 +0800 +Subject: genirq: Prevent NULL pointer dereference in resend_irqs() + +From: Yunfeng Ye <yeyunfeng@huawei.com> + +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> + +--- + kernel/irq/resend.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/irq/resend.c ++++ b/kernel/irq/resend.c +@@ -37,6 +37,8 @@ static void resend_irqs(unsigned long ar + irq = find_first_bit(irqs_resend, nr_irqs); + clear_bit(irq, irqs_resend); + desc = irq_to_desc(irq); ++ if (!desc) ++ continue; + local_irq_disable(); + desc->handle_irq(irq, desc); + local_irq_enable(); @@ -6,3 +6,4 @@ sctp-fix-the-link-time-qualifier-of-sctp_ctrlsock_exit.patch sctp-use-transport-pf_retrans-in-sctp_do_8_2_transport_strike.patch tcp-fix-tcp_ecn_withdraw_cwr-to-clear-tcp_ecn_queue_cwr.patch tun-fix-use-after-free-when-register-netdev-failed.patch +genirq-prevent-null-pointer-dereference-in-resend_irqs.patch |