• Silas Boyd-Wickizer's avatar
    Use get_online_cpus to avoid races involving CPU hotplug · 429227bb
    Silas Boyd-Wickizer authored
    If arch/x86/kernel/cpuid.c is a module, a CPU might offline or online
    between the for_each_online_cpu() loop and the call to
    register_hotcpu_notifier in cpuid_init or the call to
    unregister_hotcpu_notifier in cpuid_exit.  The potential races can
    lead to leaks/duplicates, attempts to destroy non-existant devices, or
    random pointer dereferences.
    
    For example, in cpuid_exit if:
    
            for_each_online_cpu(cpu)
                    cpuid_device_destroy(cpu);
            class_destroy(cpuid_class);
            __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
            <----- CPU onlines
            unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
    
    the hotcpu notifier will attempt to create a device for the
    cpuid_class, which the module already destroyed.
    
    This fix surrounds for_each_online_cpu and register_hotcpu_notifier or
    unregister_hotcpu_notifier with get_online_cpus+put_online_cpus.
    
    Tested on a VM.
    Signed-off-by: default avatarSilas Boyd-Wickizer <sbw@mit.edu>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
    429227bb
cpuid.c 5.48 KB