Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter()

If device_register() fails in cxl_pci_afu|adapter(), the device
is not added, device_unregister() can not be called in the error
path, otherwise it will cause a null-ptr-deref because of removing
not added device.

As comment of device_register() says, it should use put_device() to give
up the reference in the error path. So split device_unregister() into
device_del() and put_device(), then goes to put dev when register fails.

Fixes: f204e0b8cedd ("cxl: Driver code for powernv PCIe based cards for userspace access")
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
Acked-by: Andrew Donnellan <ajd@linux.ibm.com>
Link: https://lore.kernel.org/r/20221111145440.2426970-2-yangyingliang@huawei.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Yang Yingliang and committed by
Greg Kroah-Hartman
02cd3032 61c80d1c

+12 -8
+12 -8
drivers/misc/cxl/pci.c
··· 1164 1164 * if it returns an error! 1165 1165 */ 1166 1166 if ((rc = cxl_register_afu(afu))) 1167 - goto err_put1; 1167 + goto err_put_dev; 1168 1168 1169 1169 if ((rc = cxl_sysfs_afu_add(afu))) 1170 - goto err_put1; 1170 + goto err_del_dev; 1171 1171 1172 1172 adapter->afu[afu->slice] = afu; 1173 1173 ··· 1176 1176 1177 1177 return 0; 1178 1178 1179 - err_put1: 1179 + err_del_dev: 1180 + device_del(&afu->dev); 1181 + err_put_dev: 1180 1182 pci_deconfigure_afu(afu); 1181 1183 cxl_debugfs_afu_remove(afu); 1182 - device_unregister(&afu->dev); 1184 + put_device(&afu->dev); 1183 1185 return rc; 1184 1186 1185 1187 err_free_native: ··· 1669 1667 * even if it returns an error! 1670 1668 */ 1671 1669 if ((rc = cxl_register_adapter(adapter))) 1672 - goto err_put1; 1670 + goto err_put_dev; 1673 1671 1674 1672 if ((rc = cxl_sysfs_adapter_add(adapter))) 1675 - goto err_put1; 1673 + goto err_del_dev; 1676 1674 1677 1675 /* Release the context lock as adapter is configured */ 1678 1676 cxl_adapter_context_unlock(adapter); 1679 1677 1680 1678 return adapter; 1681 1679 1682 - err_put1: 1680 + err_del_dev: 1681 + device_del(&adapter->dev); 1682 + err_put_dev: 1683 1683 /* This should mirror cxl_remove_adapter, except without the 1684 1684 * sysfs parts 1685 1685 */ 1686 1686 cxl_debugfs_adapter_remove(adapter); 1687 1687 cxl_deconfigure_adapter(adapter); 1688 - device_unregister(&adapter->dev); 1688 + put_device(&adapter->dev); 1689 1689 return ERR_PTR(rc); 1690 1690 1691 1691 err_release: