This patch fixes a NULL pointer dereference triggered by a late target_configure_device() -> alloc_workqueue() failure that results in target_free_device() being called with DF_CONFIGURED already set, which subsequently OOPses in destroy_workqueue() code. Currently this only happens at modprobe target_core_mod time when core_dev_setup_virtual_lun0() -> target_configure_device() fails, and the explicit target_free_device() gets called. To address this bug originally introduced by commit 0fd97ccf45, go ahead and move DF_CONFIGURED to end of target_configure_device() code to handle this special failure case.
Unified · Split
| @@ -1548,8 +1548,6 @@ int target_configure_device(struct se_device *dev) · 1547 unmodified lines | ||
| 1548 | 1548 | ret = dev->transport->configure_device(dev); |
| 1549 | 1549 | if (ret) |
| 1550 | 1550 | goto out; |
| 1551 | − dev->dev_flags |= DF_CONFIGURED; | |
| 1552 | − | |
| 1553 | 1551 | /* |
| 1554 | 1552 | * XXX: there is not much point to have two different values here.. |
| 1555 | 1553 | */ |
| @@ -1611,6 +1609,8 @@ int target_configure_device(struct se_device *dev) · 55 unmodified lines | ||
| 1611 | 1609 | list_add_tail(&dev->g_dev_node, &g_device_list); |
| 1612 | 1610 | mutex_unlock(&g_device_mutex); |
| 1613 | 1611 | |
| 1612 | + dev->dev_flags |= DF_CONFIGURED; | |
| 1613 | + | |
| 1614 | 1614 | return 0; |
| 1615 | 1615 | |
| 1616 | 1616 | out_free_alua: |