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 | ret = dev->transport->configure_device(dev); | 1548 | ret = dev->transport->configure_device(dev); |
| 1549 | if (ret) | 1549 | if (ret) |
| 1550 | goto out; | 1550 | goto out; |
| 1551 | dev->dev_flags |= DF_CONFIGURED; | ||
| 1552 | |||
| 1553 | /* | 1551 | /* |
| 1554 | * XXX: there is not much point to have two different values here.. | 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 | list_add_tail(&dev->g_dev_node, &g_device_list); | 1609 | list_add_tail(&dev->g_dev_node, &g_device_list); |
| 1612 | mutex_unlock(&g_device_mutex); | 1610 | mutex_unlock(&g_device_mutex); |
| 1613 | 1611 | ||
| 1612 | dev->dev_flags |= DF_CONFIGURED; | ||
| 1613 | |||
| 1614 | return 0; | 1614 | return 0; |
| 1615 | 1615 | ||
| 1616 | out_free_alua: | 1616 | out_free_alua: |