From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932445AbbFEJsb (ORCPT ); Fri, 5 Jun 2015 05:48:31 -0400 Received: from mga11.intel.com ([192.55.52.93]:43882 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752738AbbFEJs2 (ORCPT ); Fri, 5 Jun 2015 05:48:28 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,558,1427785200"; d="scan'208";a="582599080" Message-ID: <5571706A.60009@linux.intel.com> Date: Fri, 05 Jun 2015 17:48:26 +0800 From: Jiang Liu Organization: Intel User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: Thomas Gleixner CC: Linux Kernel Mailing List Subject: Possible race window when walking irq descriptors Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Thomas, File include/linux/irqnr.h provides several helper interfaces to walk all/active irq descriptors. And the typical usage mode for those interfaces is as below: a) for_each_irq_desc(i, desc) { b) do_pre_work(); c) raw_spin_lock_irq(&desc->lock); d) deal_with_irq_desc(desc); e) raw_spin_unlock_irq(&desc->lock); f) do_post_work(); g) } When CONFIG_SPARSE_IRQ is enabled, irq descriptors will be freed when freeing an irq. Thus there's a race window between step a) and step d). Step c) may try to access already freed memory resources. Irq core uses sparse_irq_lock to protect an irq descriptor from freeing, but not all callers use sparse_irq_lock to protect returned irq descriptors. A tree-wide scanning shows that: 1) Callers acquire sparse_irq_lock when walking irq deescriptors: fs/proc/stat.c: show_stat() 2) Called from single-threaded environment: drivers/sh/intc/core.c: intc_suspend() and intc_resume() arch/ia64/hp/sim/hpsim_irq.c: hpsim_irq_init() kernel/irq/proc.c: init_irq_proc() kernel/irq/chip.c: suspend_device_irqs()/resume_device_irqs() arch/powerpc/kernel/machine_kexec.c: machine_kexec_mask_interrupts() arch/arm/kernel/machine_kexec.c: machine_kexec_mask_interrupts() arch/x86/kernel/apic/io_apic.c: init_IO_APIC_traps() 3) Called stop_machine environment during cpu_down() arch/arm/kernel/irq.c: migrate_irqs() arch/arm64/kernel/irq.c: migrate_irqs() arch/sh/kernel/irq.c: migrate_irqs() arch/xtensa/kernel/irq.c: migrate_irqs() arch/metag/kernel/irq.c: migrate_irqs() arch/powerpc/kernel/irq.c: migrate_irqs() arch/powerpc/sysdev/xics/xics-common.c:xics_migrate_irqs_away() kernel/irq/chip.c:irq_cpu_offline() arch/x86/kernel/irq.c: fixup_irqs() 4) Called during cpu_up() kernel/irq/chip.c:irq_cpu_online() arch/x86/kernel/apic/vector.c:__setup_vector_irq() 5) Called from free running process context arch/x86/kernel/topology.c: arch_register_cpu() arch/x86/kernel/apic/io_apic.c: print_IO_APICs() kernel/irq/autoprobe.c: probe_irq_on()/probe_irq_mask()/probe_irq_off() 6) Called from free running interrupt context kernel/irq/spurious.c: poll_spurious_irqs()/misrouted_irq() So seems something needs to done to protect 4), 5) and 6). Is this analysis correct? If so, I will try to work out some patches for it. Thanks! Gerry