Skip to content

Commit 3d88302

Browse files
lrq-maxdavem330
authored andcommitted
net: ethtool: not call vzalloc for zero sized memory request
NULL or ZERO_SIZE_PTR will be returned for zero sized memory request, and derefencing them will lead to a segfault so it is unnecessory to call vzalloc for zero sized memory request and not call functions which maybe derefence the NULL allocated memory this also fixes a possible memory leak if phy_ethtool_get_stats returns error, memory should be freed before exit Signed-off-by: Li RongQing <lirongqing@baidu.com> Reviewed-by: Wang Li <wangli39@baidu.com> Reviewed-by: Michal Kubecek <mkubecek@suse.cz> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c43ac97 commit 3d88302

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

net/core/ethtool.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,11 +1797,16 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
17971797
WARN_ON_ONCE(!ret);
17981798

17991799
gstrings.len = ret;
1800-
data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
1801-
if (gstrings.len && !data)
1802-
return -ENOMEM;
18031800

1804-
__ethtool_get_strings(dev, gstrings.string_set, data);
1801+
if (gstrings.len) {
1802+
data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
1803+
if (!data)
1804+
return -ENOMEM;
1805+
1806+
__ethtool_get_strings(dev, gstrings.string_set, data);
1807+
} else {
1808+
data = NULL;
1809+
}
18051810

18061811
ret = -EFAULT;
18071812
if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
@@ -1897,11 +1902,15 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
18971902
return -EFAULT;
18981903

18991904
stats.n_stats = n_stats;
1900-
data = vzalloc(array_size(n_stats, sizeof(u64)));
1901-
if (n_stats && !data)
1902-
return -ENOMEM;
19031905

1904-
ops->get_ethtool_stats(dev, &stats, data);
1906+
if (n_stats) {
1907+
data = vzalloc(array_size(n_stats, sizeof(u64)));
1908+
if (!data)
1909+
return -ENOMEM;
1910+
ops->get_ethtool_stats(dev, &stats, data);
1911+
} else {
1912+
data = NULL;
1913+
}
19051914

19061915
ret = -EFAULT;
19071916
if (copy_to_user(useraddr, &stats, sizeof(stats)))
@@ -1941,16 +1950,21 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
19411950
return -EFAULT;
19421951

19431952
stats.n_stats = n_stats;
1944-
data = vzalloc(array_size(n_stats, sizeof(u64)));
1945-
if (n_stats && !data)
1946-
return -ENOMEM;
19471953

1948-
if (dev->phydev && !ops->get_ethtool_phy_stats) {
1949-
ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
1950-
if (ret < 0)
1951-
return ret;
1954+
if (n_stats) {
1955+
data = vzalloc(array_size(n_stats, sizeof(u64)));
1956+
if (!data)
1957+
return -ENOMEM;
1958+
1959+
if (dev->phydev && !ops->get_ethtool_phy_stats) {
1960+
ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
1961+
if (ret < 0)
1962+
goto out;
1963+
} else {
1964+
ops->get_ethtool_phy_stats(dev, &stats, data);
1965+
}
19521966
} else {
1953-
ops->get_ethtool_phy_stats(dev, &stats, data);
1967+
data = NULL;
19541968
}
19551969

19561970
ret = -EFAULT;

0 commit comments

Comments
 (0)