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

net: liquidio: Add missing null pointer checks

The functions send_rx_ctrl_cmd() in both liquidio/lio_main.c and
liquidio/lio_vf_main.c do not check if the call to
octeon_alloc_soft_command() fails and returns a null pointer. Both
functions also return void so errors are not propagated back to the
caller.

Fix these issues by updating both instances of send_rx_ctrl_cmd() to
return an integer rather than void, and have them return -ENOMEM if an
allocation failure occurs. Also update all callers of send_rx_ctrl_cmd()
so that they now check the return value.

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Tom Seewald <tseewald@gmail.com>
Link: https://lore.kernel.org/r/20210503115736.2104747-66-gregkh@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Tom Seewald and committed by
Greg Kroah-Hartman
dbc97bfd 4fd798a5

+40 -15
+20 -8
drivers/net/ethernet/cavium/liquidio/lio_main.c
··· 1153 1153 * @lio: per-network private data 1154 1154 * @start_stop: whether to start or stop 1155 1155 */ 1156 - static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) 1156 + static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) 1157 1157 { 1158 1158 struct octeon_soft_command *sc; 1159 1159 union octnet_cmd *ncmd; ··· 1161 1161 int retval; 1162 1162 1163 1163 if (oct->props[lio->ifidx].rx_on == start_stop) 1164 - return; 1164 + return 0; 1165 1165 1166 1166 sc = (struct octeon_soft_command *) 1167 1167 octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, 1168 1168 16, 0); 1169 + if (!sc) { 1170 + netif_info(lio, rx_err, lio->netdev, 1171 + "Failed to allocate octeon_soft_command struct\n"); 1172 + return -ENOMEM; 1173 + } 1169 1174 1170 1175 ncmd = (union octnet_cmd *)sc->virtdptr; 1171 1176 ··· 1192 1187 if (retval == IQ_SEND_FAILED) { 1193 1188 netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n"); 1194 1189 octeon_free_soft_command(oct, sc); 1195 - return; 1196 1190 } else { 1197 1191 /* Sleep on a wait queue till the cond flag indicates that the 1198 1192 * response arrived or timed-out. 1199 1193 */ 1200 1194 retval = wait_for_sc_completion_timeout(oct, sc, 0); 1201 1195 if (retval) 1202 - return; 1196 + return retval; 1203 1197 1204 1198 oct->props[lio->ifidx].rx_on = start_stop; 1205 1199 WRITE_ONCE(sc->caller_is_done, true); 1206 1200 } 1201 + 1202 + return retval; 1207 1203 } 1208 1204 1209 1205 /** ··· 1779 1773 struct octeon_device_priv *oct_priv = 1780 1774 (struct octeon_device_priv *)oct->priv; 1781 1775 struct napi_struct *napi, *n; 1776 + int ret = 0; 1782 1777 1783 1778 if (oct->props[lio->ifidx].napi_enabled == 0) { 1784 1779 tasklet_disable(&oct_priv->droq_tasklet); ··· 1815 1808 netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n"); 1816 1809 1817 1810 /* tell Octeon to start forwarding packets to host */ 1818 - send_rx_ctrl_cmd(lio, 1); 1811 + ret = send_rx_ctrl_cmd(lio, 1); 1812 + if (ret) 1813 + return ret; 1819 1814 1820 1815 /* start periodical statistics fetch */ 1821 1816 INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats); ··· 1828 1819 dev_info(&oct->pci_dev->dev, "%s interface is opened\n", 1829 1820 netdev->name); 1830 1821 1831 - return 0; 1822 + return ret; 1832 1823 } 1833 1824 1834 1825 /** ··· 1842 1833 struct octeon_device_priv *oct_priv = 1843 1834 (struct octeon_device_priv *)oct->priv; 1844 1835 struct napi_struct *napi, *n; 1836 + int ret = 0; 1845 1837 1846 1838 ifstate_reset(lio, LIO_IFSTATE_RUNNING); 1847 1839 ··· 1859 1849 lio->link_changes++; 1860 1850 1861 1851 /* Tell Octeon that nic interface is down. */ 1862 - send_rx_ctrl_cmd(lio, 0); 1852 + ret = send_rx_ctrl_cmd(lio, 0); 1853 + if (ret) 1854 + return ret; 1863 1855 1864 1856 if (OCTEON_CN23XX_PF(oct)) { 1865 1857 if (!oct->msix_on) ··· 1896 1884 1897 1885 dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); 1898 1886 1899 - return 0; 1887 + return ret; 1900 1888 } 1901 1889 1902 1890 /**
+20 -7
drivers/net/ethernet/cavium/liquidio/lio_vf_main.c
··· 595 595 * @lio: per-network private data 596 596 * @start_stop: whether to start or stop 597 597 */ 598 - static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) 598 + static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) 599 599 { 600 600 struct octeon_device *oct = (struct octeon_device *)lio->oct_dev; 601 601 struct octeon_soft_command *sc; ··· 603 603 int retval; 604 604 605 605 if (oct->props[lio->ifidx].rx_on == start_stop) 606 - return; 606 + return 0; 607 607 608 608 sc = (struct octeon_soft_command *) 609 609 octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, 610 610 16, 0); 611 + if (!sc) { 612 + netif_info(lio, rx_err, lio->netdev, 613 + "Failed to allocate octeon_soft_command struct\n"); 614 + return -ENOMEM; 615 + } 611 616 612 617 ncmd = (union octnet_cmd *)sc->virtdptr; 613 618 ··· 640 635 */ 641 636 retval = wait_for_sc_completion_timeout(oct, sc, 0); 642 637 if (retval) 643 - return; 638 + return retval; 644 639 645 640 oct->props[lio->ifidx].rx_on = start_stop; 646 641 WRITE_ONCE(sc->caller_is_done, true); 647 642 } 643 + 644 + return retval; 648 645 } 649 646 650 647 /** ··· 913 906 struct octeon_device_priv *oct_priv = 914 907 (struct octeon_device_priv *)oct->priv; 915 908 struct napi_struct *napi, *n; 909 + int ret = 0; 916 910 917 911 if (!oct->props[lio->ifidx].napi_enabled) { 918 912 tasklet_disable(&oct_priv->droq_tasklet); ··· 940 932 (LIQUIDIO_NDEV_STATS_POLL_TIME_MS)); 941 933 942 934 /* tell Octeon to start forwarding packets to host */ 943 - send_rx_ctrl_cmd(lio, 1); 935 + ret = send_rx_ctrl_cmd(lio, 1); 936 + if (ret) 937 + return ret; 944 938 945 939 dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name); 946 940 947 - return 0; 941 + return ret; 948 942 } 949 943 950 944 /** ··· 960 950 struct octeon_device_priv *oct_priv = 961 951 (struct octeon_device_priv *)oct->priv; 962 952 struct napi_struct *napi, *n; 953 + int ret = 0; 963 954 964 955 /* tell Octeon to stop forwarding packets to host */ 965 - send_rx_ctrl_cmd(lio, 0); 956 + ret = send_rx_ctrl_cmd(lio, 0); 957 + if (ret) 958 + return ret; 966 959 967 960 netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n"); 968 961 /* Inform that netif carrier is down */ ··· 999 986 1000 987 dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); 1001 988 1002 - return 0; 989 + return ret; 1003 990 } 1004 991 1005 992 /**