]>
Commit | Line | Data |
---|---|---|
9354405a GKH |
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 | 43 +++++++++++++++++++++++++++---------------- | |
27 | 1 file changed, 27 insertions(+), 16 deletions(-) | |
28 | ||
29 | --- a/net/core/ethtool.c | |
30 | +++ b/net/core/ethtool.c | |
31 | @@ -1815,11 +1815,15 @@ static int ethtool_get_strings(struct ne | |
32 | WARN_ON_ONCE(!ret); | |
33 | ||
34 | gstrings.len = ret; | |
35 | - data = vzalloc(gstrings.len * ETH_GSTRING_LEN); | |
36 | - if (gstrings.len && !data) | |
37 | - return -ENOMEM; | |
38 | + if (gstrings.len) { | |
39 | + data = vzalloc(gstrings.len * ETH_GSTRING_LEN); | |
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 | @@ -1915,11 +1919,14 @@ static int ethtool_get_stats(struct net_ | |
52 | return -EFAULT; | |
53 | ||
54 | stats.n_stats = n_stats; | |
55 | - data = vzalloc(n_stats * sizeof(u64)); | |
56 | - if (n_stats && !data) | |
57 | - return -ENOMEM; | |
58 | - | |
59 | - ops->get_ethtool_stats(dev, &stats, data); | |
60 | + if (n_stats) { | |
61 | + data = vzalloc(n_stats * sizeof(u64)); | |
62 | + if (!data) | |
63 | + return -ENOMEM; | |
64 | + ops->get_ethtool_stats(dev, &stats, data); | |
65 | + } else { | |
66 | + data = NULL; | |
67 | + } | |
68 | ||
69 | ret = -EFAULT; | |
70 | if (copy_to_user(useraddr, &stats, sizeof(stats))) | |
71 | @@ -1955,13 +1962,17 @@ static int ethtool_get_phy_stats(struct | |
72 | return -EFAULT; | |
73 | ||
74 | stats.n_stats = n_stats; | |
75 | - data = vzalloc(n_stats * sizeof(u64)); | |
76 | - if (n_stats && !data) | |
77 | - return -ENOMEM; | |
78 | - | |
79 | - mutex_lock(&phydev->lock); | |
80 | - phydev->drv->get_stats(phydev, &stats, data); | |
81 | - mutex_unlock(&phydev->lock); | |
82 | + if (n_stats) { | |
83 | + data = vzalloc(n_stats * sizeof(u64)); | |
84 | + if (!data) | |
85 | + return -ENOMEM; | |
86 | + | |
87 | + mutex_lock(&phydev->lock); | |
88 | + phydev->drv->get_stats(phydev, &stats, data); | |
89 | + mutex_unlock(&phydev->lock); | |
90 | + } else { | |
91 | + data = NULL; | |
92 | + } | |
93 | ||
94 | ret = -EFAULT; | |
95 | if (copy_to_user(useraddr, &stats, sizeof(stats))) |