]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-3.18/net-ethtool-not-call-vzalloc-for-zero-sized-memory-request.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / queue-3.18 / net-ethtool-not-call-vzalloc-for-zero-sized-memory-request.patch
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
5
6 From: Li RongQing <lirongqing@baidu.com>
7
8 [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ]
9
10 NULL or ZERO_SIZE_PTR will be returned for zero sized memory
11 request, and derefencing them will lead to a segfault
12
13 so it is unnecessory to call vzalloc for zero sized memory
14 request and not call functions which maybe derefence the
15 NULL allocated memory
16
17 this also fixes a possible memory leak if phy_ethtool_get_stats
18 returns error, memory should be freed before exit
19
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>
25 ---
26 net/core/ethtool.c | 29 +++++++++++++++++++----------
27 1 file changed, 19 insertions(+), 10 deletions(-)
28
29 --- a/net/core/ethtool.c
30 +++ b/net/core/ethtool.c
31 @@ -1257,17 +1257,22 @@ static int ethtool_get_strings(struct ne
32
33 gstrings.len = ret;
34
35 - data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
36 - if (!data)
37 - return -ENOMEM;
38 + if (gstrings.len) {
39 + data = kcalloc(gstrings.len, ETH_GSTRING_LEN, GFP_USER);
40 + if (!data)
41 + return -ENOMEM;
42
43 - __ethtool_get_strings(dev, gstrings.string_set, data);
44 + __ethtool_get_strings(dev, gstrings.string_set, data);
45 + } else {
46 + data = NULL;
47 + }
48
49 ret = -EFAULT;
50 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
51 goto out;
52 useraddr += sizeof(gstrings);
53 - if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
54 + if (gstrings.len &&
55 + copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
56 goto out;
57 ret = 0;
58
59 @@ -1355,17 +1360,21 @@ static int ethtool_get_stats(struct net_
60 return -EFAULT;
61
62 stats.n_stats = n_stats;
63 - data = kmalloc(n_stats * sizeof(u64), GFP_USER);
64 - if (!data)
65 - return -ENOMEM;
66 + if (n_stats) {
67 + data = kmalloc(n_stats * sizeof(u64), GFP_USER);
68 + if (!data)
69 + return -ENOMEM;
70
71 - ops->get_ethtool_stats(dev, &stats, data);
72 + ops->get_ethtool_stats(dev, &stats, data);
73 + } else {
74 + data = NULL;
75 + }
76
77 ret = -EFAULT;
78 if (copy_to_user(useraddr, &stats, sizeof(stats)))
79 goto out;
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)))
83 goto out;
84 ret = 0;
85