aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-16 21:28:54 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-16 21:28:54 +0200
commitb498eaeb80bda9693a5158b3c13924f71aae7afa (patch)
tree93129f16791a5fa0e6cead834c65798e2d052fb0
parent2f2387e5223e1aa80876261d423f8ce7242ebe89 (diff)
downloadqueue-3.18-b498eaeb80bda9693a5158b3c13924f71aae7afa.tar.gz
another
-rw-r--r--genirq-prevent-null-pointer-dereference-in-resend_irqs.patch76
-rw-r--r--series1
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();
diff --git a/series b/series
index e04ee79..e1a67e4 100644
--- a/series
+++ b/series
@@ -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