Patch "x86/irq: Fix a race in x86_vector_free_irqs()" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
x86/irq: Fix a race in x86_vector_free_irqs()
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-irq-fix-a-race-in-x86_vector_free_irqs.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
111abeba67e0dbdc26537429de9155e4f1d807d8Mon Sep 17 00:00:00 2001
From: Jiang Liu <[email protected]>
Date: Thu, 31 Dec 2015 16:30:44 +0000
Subject: x86/irq: Fix a race in x86_vector_free_irqs()
From: Jiang Liu <[email protected]>
commit 111abeba67e0dbdc26537429de9155e4f1d807d8 upstream.
There's a race condition between
x86_vector_free_irqs()
{
free_apic_chip_data(irq_data->chip_data);
xxxxx //irq_data->chip_data has been freed, but the pointer
//hasn't been reset yet
irq_domain_reset_irq_data(irq_data);
}and
smp_irq_move_cleanup_interrupt()
{
raw_spin_lock(&vector_lock);
data = apic_chip_data(irq_desc_get_irq_data(desc));
access data->xxxx // may access freed memory
raw_spin_unlock(&desc->lock);
}which may cause smp_irq_move_cleanup_interrupt() to access freed memory.
Call irq_domain_reset_irq_data(), which clears the pointer with vector lock held.
[ tglx: Free memory outside of lock held region. ]
--- arch/x86/kernel/apic/vector.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/apic/vector.c +8 -8
@@ -224,10 +224,8 @@ static int assign_irq_vector_policy(intstatic void clear_irq_vector (int irq,struct apic_chip_data *data) {struct irq_desc *desc; -unsigned long flags;int cpu, vector; -raw_spin_lock_irqsave (&vector_lock, flags);BUG_ON (!data->cfg.vector); vector = data->cfg.vector;
@@ -237,10 +235,8 @@ static void clear_irq_vector(int irq, st data->cfg.vector =0 ;cpumask_clear (data->domain); -if (likely (!data->move_in_progress)) { -raw_spin_unlock_irqrestore (&vector_lock, flags); +if (likely (!data->move_in_progress))return ; - } desc =irq_to_desc (irq);for_each_cpu_and (cpu, data->old_domain, cpu_online_mask) {
@@ -253,7 +249,6 @@ static void clear_irq_vector(int irq, st } } data->move_in_progress =0 ; -raw_spin_unlock_irqrestore (&vector_lock, flags); } void init_irq_alloc_info(struct irq_alloc_info *info,
@@ -274,19 +269,24 @@ void copy_irq_alloc_info(struct irq_allostatic void x86_vector_free_irqs (struct irq_domain *domain,unsigned int virq,unsigned int nr_irqs) { +struct apic_chip_data *apic_data;struct irq_data *irq_data; +unsigned long flags;int i;for (i =0 ; i < nr_irqs; i++) { irq_data =irq_domain_get_irq_data (x86_vector_domain, virq + i);if (irq_data && irq_data->chip_data) { +raw_spin_lock_irqsave (&vector_lock, flags);clear_irq_vector (virq + i, irq_data->chip_data); -free_apic_chip_data (irq_data->chip_data); + apic_data = irq_data->chip_data; +irq_domain_reset_irq_data (irq_data); +raw_spin_unlock_irqrestore (&vector_lock, flags); +free_apic_chip_data (apic_data);#ifdef CONFIG_X86_IO_APIC if (virq + i <nr_legacy_irqs ()) legacy_irq_data[virq + i] =NULL ;#endif -irq_domain_reset_irq_data (irq_data); } } }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/x86-irq-validate-that-irq-descriptor-is-still-active.patch queue-4.4/x86-irq-remove-outgoing-cpu-from-vector-cleanup-mask.patch queue-4.4/x86-irq-get-rid-of-code-duplication.patch queue-4.4/genirq-validate-action-before-dereferencing-it-in-handle_irq_event_percpu.patch queue-4.4/x86-irq-remove-offline-cpus-from-vector-cleanup.patch queue-4.4/x86-irq-reorganize-the-return-path-in-assign_irq_vector.patch queue-4.4/x86-irq-copy-vectormask-instead-of-an-and-operation.patch queue-4.4/x86-irq-call-irq_force_move_complete-with-irq-descriptor.patch queue-4.4/x86-irq-call-chip-irq_set_affinity-in-proper-context.patch queue-4.4/x86-irq-plug-vector-cleanup-race.patch queue-4.4/x86-irq-do-not-use-apic_chip_data.old_domain-as-temporary-buffer.patch queue-4.4/x86-irq-reorganize-the-search-in-assign_irq_vector.patch queue-4.4/x86-irq-remove-the-cpumask-allocation-from-send_cleanup_vector.patch queue-4.4/x86-irq-fix-a-race-in-x86_vector_free_irqs.patch queue-4.4/x86-irq-check-vector-allocation-early.patch queue-4.4/x86-irq-clear-move_in_progress-before-sending-cleanup-ipi.patch