1 From foo@baz Mon Apr 15 07:47:06 CEST 2019
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 From: Li RongQing <lirongqing@baidu.com>
8 [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ]
10 NULL or ZERO_SIZE_PTR will be returned for zero sized memory
11 request, and derefencing them will lead to a segfault
13 so it is unnecessory to call vzalloc for zero sized memory
14 request and not call functions which maybe derefence the
17 this also fixes a possible memory leak if phy_ethtool_get_stats
18 returns error, memory should be freed before exit
20 Signed-off-by: Li RongQing <lirongqing@baidu.com>
21 Reviewed-by: Wang Li <wangli39@baidu.com>
22 Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
23 Signed-off-by: David S. Miller <davem@davemloft.net>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26 net/core/ethtool.c | 29 +++++++++++++++++++----------
27 1 file changed, 19 insertions(+), 10 deletions(-)
29 --- a/net/core/ethtool.c
30 +++ b/net/core/ethtool.c
31 @@ -1257,17 +1257,22 @@ static int ethtool_get_strings(struct ne
35 - data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
39 + data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
43 - __ethtool_get_strings(dev, gstrings.string_set, data);
44 + __ethtool_get_strings(dev, gstrings.string_set, data);
50 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
52 useraddr += sizeof(gstrings);
53 - if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
55 + copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
59 @@ -1355,17 +1360,21 @@ static int ethtool_get_stats(struct net_
62 stats.n_stats = n_stats;
63 - data = kmalloc(n_stats * sizeof(u64), GFP_USER);
67 + data = kmalloc(n_stats * sizeof(u64), GFP_USER);
71 - ops->get_ethtool_stats(dev, &stats, data);
72 + ops->get_ethtool_stats(dev, &stats, data);
78 if (copy_to_user(useraddr, &stats, sizeof(stats)))
80 useraddr += sizeof(stats);
81 - if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64)))
82 + if (n_stats && copy_to_user(useraddr, data, n_stats * sizeof(u64)))