• M
    firmware loader: fix pending_fw_head list corruption · 1eeeef15
    Maxime Bizon 提交于
    Got the following oops just before reboot:
    
    Unable to handle kernel NULL pointer dereference at virtual address 00000000
    [<8028d300>] (__list_del_entry+0x44/0xac)
    [<802e3320>] (__fw_load_abort.part.13+0x1c/0x50)
    [<802e337c>] (fw_shutdown_notify+0x28/0x50)
    [<80034f80>] (notifier_call_chain.isra.1+0x5c/0x9c)
    [<800350ec>] (__blocking_notifier_call_chain+0x44/0x58)
    [<80035114>] (blocking_notifier_call_chain+0x14/0x18)
    [<80035d64>] (kernel_restart_prepare+0x14/0x38)
    [<80035d94>] (kernel_restart+0xc/0x50)
    
    The following race condition triggers here:
    
      _request_firmware_load()
      device_create_file(...)
      kobject_uevent(...)
      (schedule)
                                           (resume)
                                           firmware_loading_store(1)
                                           firmware_loading_store(0)
                                           list_del_init(&buf->pending_list)
                                           (schedule)
      (resume)
      list_add(&buf->pending_list, &pending_fw_head);
      wait_for_completion(&buf->completion);
    
    causing an oops later when walking pending_list after the firmware has
    been released.
    
    The proposed fix is to move the list_add() before sysfs attribute
    creation.
    Signed-off-by: NMaxime Bizon <mbizon@freebox.fr>
    Acked-by: NMing Lei <ming.lei@canonical.com>
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    1eeeef15
firmware_class.c 37.3 KB