]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.35/net-ethtool-not-call-vzalloc-for-zero-sized-memory-r.patch
Linux 4.19.35
[thirdparty/kernel/stable-queue.git] / releases / 4.19.35 / net-ethtool-not-call-vzalloc-for-zero-sized-memory-r.patch
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
5
6 [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ]
7
8 NULL or ZERO_SIZE_PTR will be returned for zero sized memory
9 request, and derefencing them will lead to a segfault
10
11 so it is unnecessory to call vzalloc for zero sized memory
12 request and not call functions which maybe derefence the
13 NULL allocated memory
14
15 this also fixes a possible memory leak if phy_ethtool_get_stats
16 returns error, memory should be freed before exit
17
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>
23 ---
24 net/core/ethtool.c | 46 ++++++++++++++++++++++++++++++----------------
25 1 file changed, 30 insertions(+), 16 deletions(-)
26
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)
32 WARN_ON_ONCE(!ret);
33
34 gstrings.len = ret;
35 - data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
36 - if (gstrings.len && !data)
37 - return -ENOMEM;
38
39 - __ethtool_get_strings(dev, gstrings.string_set, data);
40 + if (gstrings.len) {
41 + data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
42 + if (!data)
43 + return -ENOMEM;
44 +
45 + __ethtool_get_strings(dev, gstrings.string_set, data);
46 + } else {
47 + data = NULL;
48 + }
49
50 ret = -EFAULT;
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)
53 return -EFAULT;
54
55 stats.n_stats = n_stats;
56 - data = vzalloc(array_size(n_stats, sizeof(u64)));
57 - if (n_stats && !data)
58 - return -ENOMEM;
59
60 - ops->get_ethtool_stats(dev, &stats, data);
61 + if (n_stats) {
62 + data = vzalloc(array_size(n_stats, sizeof(u64)));
63 + if (!data)
64 + return -ENOMEM;
65 + ops->get_ethtool_stats(dev, &stats, data);
66 + } else {
67 + data = NULL;
68 + }
69
70 ret = -EFAULT;
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)
73 return -EFAULT;
74
75 stats.n_stats = n_stats;
76 - data = vzalloc(array_size(n_stats, sizeof(u64)));
77 - if (n_stats && !data)
78 - return -ENOMEM;
79
80 - if (dev->phydev && !ops->get_ethtool_phy_stats) {
81 - ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
82 - if (ret < 0)
83 - return ret;
84 + if (n_stats) {
85 + data = vzalloc(array_size(n_stats, sizeof(u64)));
86 + if (!data)
87 + return -ENOMEM;
88 +
89 + if (dev->phydev && !ops->get_ethtool_phy_stats) {
90 + ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
91 + if (ret < 0)
92 + goto out;
93 + } else {
94 + ops->get_ethtool_phy_stats(dev, &stats, data);
95 + }
96 } else {
97 - ops->get_ethtool_phy_stats(dev, &stats, data);
98 + data = NULL;
99 }
100
101 ret = -EFAULT;
102 --
103 2.19.1
104