1 From 3a081f59018c59dc7f4f8ee4ffb3c3c0fae2cffb Mon Sep 17 00:00:00 2001
2 From: Li RongQing <lirongqing@baidu.com>
3 Date: Fri, 29 Mar 2019 09:18:02 +0800
4 Subject: net: ethtool: not call vzalloc for zero sized memory request
6 [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ]
8 NULL or ZERO_SIZE_PTR will be returned for zero sized memory
9 request, and derefencing them will lead to a segfault
11 so it is unnecessory to call vzalloc for zero sized memory
12 request and not call functions which maybe derefence the
15 this also fixes a possible memory leak if phy_ethtool_get_stats
16 returns error, memory should be freed before exit
18 Signed-off-by: Li RongQing <lirongqing@baidu.com>
19 Reviewed-by: Wang Li <wangli39@baidu.com>
20 Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
21 Signed-off-by: David S. Miller <davem@davemloft.net>
22 Signed-off-by: Sasha Levin <sashal@kernel.org>
24 net/core/ethtool.c | 46 ++++++++++++++++++++++++++++++----------------
25 1 file changed, 30 insertions(+), 16 deletions(-)
27 diff --git a/net/core/ethtool.c b/net/core/ethtool.c
28 index aeabc4831fca..7cc97f43f138 100644
29 --- a/net/core/ethtool.c
30 +++ b/net/core/ethtool.c
31 @@ -1863,11 +1863,16 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
35 - data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
36 - if (gstrings.len && !data)
39 - __ethtool_get_strings(dev, gstrings.string_set, data);
41 + data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
45 + __ethtool_get_strings(dev, gstrings.string_set, data);
51 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
52 @@ -1963,11 +1968,15 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
55 stats.n_stats = n_stats;
56 - data = vzalloc(array_size(n_stats, sizeof(u64)));
57 - if (n_stats && !data)
60 - ops->get_ethtool_stats(dev, &stats, data);
62 + data = vzalloc(array_size(n_stats, sizeof(u64)));
65 + ops->get_ethtool_stats(dev, &stats, data);
71 if (copy_to_user(useraddr, &stats, sizeof(stats)))
72 @@ -2007,16 +2016,21 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
75 stats.n_stats = n_stats;
76 - data = vzalloc(array_size(n_stats, sizeof(u64)));
77 - if (n_stats && !data)
80 - if (dev->phydev && !ops->get_ethtool_phy_stats) {
81 - ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
85 + data = vzalloc(array_size(n_stats, sizeof(u64)));
89 + if (dev->phydev && !ops->get_ethtool_phy_stats) {
90 + ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
94 + ops->get_ethtool_phy_stats(dev, &stats, data);
97 - ops->get_ethtool_phy_stats(dev, &stats, data);