]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: liquidio: Initialize netdev pointer before queue setup
authorZilin Guan <zilin@seu.edu.cn>
Wed, 28 Jan 2026 15:44:38 +0000 (15:44 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 30 Jan 2026 03:27:35 +0000 (19:27 -0800)
In setup_nic_devices(), the netdev is allocated using alloc_etherdev_mq().
However, the pointer to this structure is stored in oct->props[i].netdev
only after the calls to netif_set_real_num_rx_queues() and
netif_set_real_num_tx_queues().

If either of these functions fails, setup_nic_devices() returns an error
without freeing the allocated netdev. Since oct->props[i].netdev is still
NULL at this point, the cleanup function liquidio_destroy_nic_device()
will fail to find and free the netdev, resulting in a memory leak.

Fix this by initializing oct->props[i].netdev before calling the queue
setup functions. This ensures that the netdev is properly accessible for
cleanup in case of errors.

Compile tested only. Issue found using a prototype static analysis tool
and code review.

Fixes: c33c997346c3 ("liquidio: enhanced ethtool --set-channels feature")
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
Link: https://patch.msgid.link/20260128154440.278369-2-zilin@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/cavium/liquidio/lio_main.c

index 0732440eeacd62e84d6840155cc99fafd12878a3..1f10b1b22a1e4ad9c616f75c5817d53965d276c9 100644 (file)
@@ -3505,6 +3505,23 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
                 */
                netdev->netdev_ops = &lionetdevops;
 
+               lio = GET_LIO(netdev);
+
+               memset(lio, 0, sizeof(struct lio));
+
+               lio->ifidx = ifidx_or_pfnum;
+
+               props = &octeon_dev->props[i];
+               props->gmxport = resp->cfg_info.linfo.gmxport;
+               props->netdev = netdev;
+
+               /* Point to the  properties for octeon device to which this
+                * interface belongs.
+                */
+               lio->oct_dev = octeon_dev;
+               lio->octprops = props;
+               lio->netdev = netdev;
+
                retval = netif_set_real_num_rx_queues(netdev, num_oqueues);
                if (retval) {
                        dev_err(&octeon_dev->pci_dev->dev,
@@ -3521,16 +3538,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
                        goto setup_nic_dev_free;
                }
 
-               lio = GET_LIO(netdev);
-
-               memset(lio, 0, sizeof(struct lio));
-
-               lio->ifidx = ifidx_or_pfnum;
-
-               props = &octeon_dev->props[i];
-               props->gmxport = resp->cfg_info.linfo.gmxport;
-               props->netdev = netdev;
-
                lio->linfo.num_rxpciq = num_oqueues;
                lio->linfo.num_txpciq = num_iqueues;
                for (j = 0; j < num_oqueues; j++) {
@@ -3596,13 +3603,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
                netdev->min_mtu = LIO_MIN_MTU_SIZE;
                netdev->max_mtu = LIO_MAX_MTU_SIZE;
 
-               /* Point to the  properties for octeon device to which this
-                * interface belongs.
-                */
-               lio->oct_dev = octeon_dev;
-               lio->octprops = props;
-               lio->netdev = netdev;
-
                dev_dbg(&octeon_dev->pci_dev->dev,
                        "if%d gmx: %d hw_addr: 0x%llx\n", i,
                        lio->linfo.gmxport, CVM_CAST64(lio->linfo.hw_addr));