From 94dc27cf31c80196c16731145fb608d4331200f4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 26 May 2021 10:06:04 +0800 Subject: [PATCH] genirq: Sanitize state handling in check_irq_resend() mainline inclusion from mainline-5.7 commit da90921acc62c71d27729ae211ccfda5370bf75b category: bugfix bugzilla: NA CVE: NA ------------------------------------------------- The code sets IRQS_REPLAY unconditionally whether the resend happens or not. That doesn't have bad side effects right now, but inconsistent state is always a latent source of problems. Signed-off-by: Thomas Gleixner Acked-by: Marc Zyngier Link: https://lkml.kernel.org/r/20200306130623.882129117@linutronix.de Signed-off-by: Liao Chang Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- kernel/irq/resend.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 1faf8991adbb..7de48bc06c75 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c @@ -105,6 +105,7 @@ static int try_retrigger(struct irq_desc *desc) */ int check_irq_resend(struct irq_desc *desc) { + int err = 0; /* * We do not resend level type interrupts. Level type interrupts @@ -118,11 +119,16 @@ int check_irq_resend(struct irq_desc *desc) if (desc->istate & IRQS_REPLAY) return -EBUSY; - if (desc->istate & IRQS_PENDING) { - desc->istate &= ~IRQS_PENDING; + if (!(desc->istate & IRQS_PENDING)) + return 0; + + desc->istate &= ~IRQS_PENDING; + + if (!try_retrigger(desc)) + err = irq_sw_resend(desc); + + /* If the retrigger was successfull, mark it with the REPLAY bit */ + if (!err) desc->istate |= IRQS_REPLAY; - if (!try_retrigger(desc)) - return irq_sw_resend(desc); - } - return 0; + return err; } -- GitLab