If rio_add_device() fails, call rio_free_net() to unregister the net device registered by rio_add_net().
Fixes: e8de370188d0 ("rapidio: add mport char device driver") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li lihaoxiang@isrc.iscas.ac.cn --- drivers/rapidio/devices/rio_mport_cdev.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 995cfeca972b..4a804b4ad6f7 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -1789,6 +1789,7 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, err = rio_add_device(rdev); if (err) { put_device(&rdev->dev); + rio_free_net(net); return err; }
On Sun, Dec 21, 2025 at 08:05:38PM +0800, Haoxiang Li wrote:
If rio_add_device() fails, call rio_free_net() to unregister the net device registered by rio_add_net().
Fixes: e8de370188d0 ("rapidio: add mport char device driver") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li lihaoxiang@isrc.iscas.ac.cn
drivers/rapidio/devices/rio_mport_cdev.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 995cfeca972b..4a804b4ad6f7 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -1789,6 +1789,7 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, err = rio_add_device(rdev); if (err) { put_device(&rdev->dev);
return err;rio_free_net(net);
Are you sure this is right? You aren't checking that rio_add_net() was actually called. How was this tested? How was this found? What tool was used to find it?
thanks,
greg k-h
Hi Haoxiang,
kernel test robot noticed the following build errors:
[auto build test ERROR on akpm-mm/mm-everything] [also build test ERROR on linus/master v6.19-rc2 next-20251219] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Haoxiang-Li/rapidio-fix-a-res... base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20251221120538.947670-1-lihaoxiang%40isrc.iscas.ac... patch subject: [PATCH] rapidio: fix a resource leak when rio_add_device() fails config: x86_64-buildonly-randconfig-003-20251223 (https://download.01.org/0day-ci/archive/20251223/202512230711.jyQOu79S-lkp@i...) compiler: gcc-14 (Debian 14.2.0-19) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251223/202512230711.jyQOu79S-lkp@i...)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202512230711.jyQOu79S-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/rapidio/devices/rio_mport_cdev.c: In function 'rio_mport_add_riodev':
drivers/rapidio/devices/rio_mport_cdev.c:1792:30: error: 'net' undeclared (first use in this function)
1792 | rio_free_net(net); | ^~~ drivers/rapidio/devices/rio_mport_cdev.c:1792:30: note: each undeclared identifier is reported only once for each function it appears in
vim +/net +1792 drivers/rapidio/devices/rio_mport_cdev.c
1648 1649 1650 /* 1651 * rio_mport_add_riodev - creates a kernel RIO device object 1652 * 1653 * Allocates a RIO device data structure and initializes required fields based 1654 * on device's configuration space contents. 1655 * If the device has switch capabilities, then a switch specific portion is 1656 * allocated and configured. 1657 */ 1658 static int rio_mport_add_riodev(struct mport_cdev_priv *priv, 1659 void __user *arg) 1660 { 1661 struct mport_dev *md = priv->md; 1662 struct rio_rdev_info dev_info; 1663 struct rio_dev *rdev; 1664 struct rio_switch *rswitch = NULL; 1665 struct rio_mport *mport; 1666 struct device *dev; 1667 size_t size; 1668 u32 rval; 1669 u32 swpinfo = 0; 1670 u16 destid; 1671 u8 hopcount; 1672 int err; 1673 1674 if (copy_from_user(&dev_info, arg, sizeof(dev_info))) 1675 return -EFAULT; 1676 dev_info.name[sizeof(dev_info.name) - 1] = '\0'; 1677 1678 rmcd_debug(RDEV, "name:%s ct:0x%x did:0x%x hc:0x%x", dev_info.name, 1679 dev_info.comptag, dev_info.destid, dev_info.hopcount); 1680 1681 dev = bus_find_device_by_name(&rio_bus_type, NULL, dev_info.name); 1682 if (dev) { 1683 rmcd_debug(RDEV, "device %s already exists", dev_info.name); 1684 put_device(dev); 1685 return -EEXIST; 1686 } 1687 1688 size = sizeof(*rdev); 1689 mport = md->mport; 1690 destid = dev_info.destid; 1691 hopcount = dev_info.hopcount; 1692 1693 if (rio_mport_read_config_32(mport, destid, hopcount, 1694 RIO_PEF_CAR, &rval)) 1695 return -EIO; 1696 1697 if (rval & RIO_PEF_SWITCH) { 1698 rio_mport_read_config_32(mport, destid, hopcount, 1699 RIO_SWP_INFO_CAR, &swpinfo); 1700 size += struct_size(rswitch, nextdev, RIO_GET_TOTAL_PORTS(swpinfo)); 1701 } 1702 1703 rdev = kzalloc(size, GFP_KERNEL); 1704 if (rdev == NULL) 1705 return -ENOMEM; 1706 1707 if (mport->net == NULL) { 1708 struct rio_net *net; 1709 1710 net = rio_alloc_net(mport); 1711 if (!net) { 1712 err = -ENOMEM; 1713 rmcd_debug(RDEV, "failed to allocate net object"); 1714 goto cleanup; 1715 } 1716 1717 net->id = mport->id; 1718 net->hport = mport; 1719 dev_set_name(&net->dev, "rnet_%d", net->id); 1720 net->dev.parent = &mport->dev; 1721 net->dev.release = rio_release_net; 1722 err = rio_add_net(net); 1723 if (err) { 1724 rmcd_debug(RDEV, "failed to register net, err=%d", err); 1725 put_device(&net->dev); 1726 mport->net = NULL; 1727 goto cleanup; 1728 } 1729 } 1730 1731 rdev->net = mport->net; 1732 rdev->pef = rval; 1733 rdev->swpinfo = swpinfo; 1734 rio_mport_read_config_32(mport, destid, hopcount, 1735 RIO_DEV_ID_CAR, &rval); 1736 rdev->did = rval >> 16; 1737 rdev->vid = rval & 0xffff; 1738 rio_mport_read_config_32(mport, destid, hopcount, RIO_DEV_INFO_CAR, 1739 &rdev->device_rev); 1740 rio_mport_read_config_32(mport, destid, hopcount, RIO_ASM_ID_CAR, 1741 &rval); 1742 rdev->asm_did = rval >> 16; 1743 rdev->asm_vid = rval & 0xffff; 1744 rio_mport_read_config_32(mport, destid, hopcount, RIO_ASM_INFO_CAR, 1745 &rval); 1746 rdev->asm_rev = rval >> 16; 1747 1748 if (rdev->pef & RIO_PEF_EXT_FEATURES) { 1749 rdev->efptr = rval & 0xffff; 1750 rdev->phys_efptr = rio_mport_get_physefb(mport, 0, destid, 1751 hopcount, &rdev->phys_rmap); 1752 1753 rdev->em_efptr = rio_mport_get_feature(mport, 0, destid, 1754 hopcount, RIO_EFB_ERR_MGMNT); 1755 } 1756 1757 rio_mport_read_config_32(mport, destid, hopcount, RIO_SRC_OPS_CAR, 1758 &rdev->src_ops); 1759 rio_mport_read_config_32(mport, destid, hopcount, RIO_DST_OPS_CAR, 1760 &rdev->dst_ops); 1761 1762 rdev->comp_tag = dev_info.comptag; 1763 rdev->destid = destid; 1764 /* hopcount is stored as specified by a caller, regardles of EP or SW */ 1765 rdev->hopcount = hopcount; 1766 1767 if (rdev->pef & RIO_PEF_SWITCH) { 1768 rswitch = rdev->rswitch; 1769 rswitch->route_table = NULL; 1770 } 1771 1772 if (strlen(dev_info.name)) 1773 dev_set_name(&rdev->dev, "%s", dev_info.name); 1774 else if (rdev->pef & RIO_PEF_SWITCH) 1775 dev_set_name(&rdev->dev, "%02x:s:%04x", mport->id, 1776 rdev->comp_tag & RIO_CTAG_UDEVID); 1777 else 1778 dev_set_name(&rdev->dev, "%02x:e:%04x", mport->id, 1779 rdev->comp_tag & RIO_CTAG_UDEVID); 1780 1781 INIT_LIST_HEAD(&rdev->net_list); 1782 rdev->dev.parent = &mport->net->dev; 1783 rio_attach_device(rdev); 1784 rdev->dev.release = rio_release_dev; 1785 1786 if (rdev->dst_ops & RIO_DST_OPS_DOORBELL) 1787 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE], 1788 0, 0xffff); 1789 err = rio_add_device(rdev); 1790 if (err) { 1791 put_device(&rdev->dev);
1792 rio_free_net(net);
1793 return err; 1794 } 1795 1796 rio_dev_get(rdev); 1797 1798 return 0; 1799 cleanup: 1800 kfree(rdev); 1801 return err; 1802 } 1803
linux-stable-mirror@lists.linaro.org