lkml.org 
[lkml]   [2019]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 010/101] net: ethtool: not call vzalloc for zero sized memory request
    Date
    [ Upstream commit 3d8830266ffc28c16032b859e38a0252e014b631 ]

    NULL or ZERO_SIZE_PTR will be returned for zero sized memory
    request, and derefencing them will lead to a segfault

    so it is unnecessory to call vzalloc for zero sized memory
    request and not call functions which maybe derefence the
    NULL allocated memory

    this also fixes a possible memory leak if phy_ethtool_get_stats
    returns error, memory should be freed before exit

    Signed-off-by: Li RongQing <lirongqing@baidu.com>
    Reviewed-by: Wang Li <wangli39@baidu.com>
    Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/core/ethtool.c | 46 ++++++++++++++++++++++++++++++----------------
    1 file changed, 30 insertions(+), 16 deletions(-)

    diff --git a/net/core/ethtool.c b/net/core/ethtool.c
    index aeabc4831fca..7cc97f43f138 100644
    --- a/net/core/ethtool.c
    +++ b/net/core/ethtool.c
    @@ -1863,11 +1863,16 @@ static int ethtool_get_strings(struct net_device *dev, void __user *useraddr)
    WARN_ON_ONCE(!ret);

    gstrings.len = ret;
    - data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
    - if (gstrings.len && !data)
    - return -ENOMEM;

    - __ethtool_get_strings(dev, gstrings.string_set, data);
    + if (gstrings.len) {
    + data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
    + if (!data)
    + return -ENOMEM;
    +
    + __ethtool_get_strings(dev, gstrings.string_set, data);
    + } else {
    + data = NULL;
    + }

    ret = -EFAULT;
    if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
    @@ -1963,11 +1968,15 @@ static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
    return -EFAULT;

    stats.n_stats = n_stats;
    - data = vzalloc(array_size(n_stats, sizeof(u64)));
    - if (n_stats && !data)
    - return -ENOMEM;

    - ops->get_ethtool_stats(dev, &stats, data);
    + if (n_stats) {
    + data = vzalloc(array_size(n_stats, sizeof(u64)));
    + if (!data)
    + return -ENOMEM;
    + ops->get_ethtool_stats(dev, &stats, data);
    + } else {
    + data = NULL;
    + }

    ret = -EFAULT;
    if (copy_to_user(useraddr, &stats, sizeof(stats)))
    @@ -2007,16 +2016,21 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
    return -EFAULT;

    stats.n_stats = n_stats;
    - data = vzalloc(array_size(n_stats, sizeof(u64)));
    - if (n_stats && !data)
    - return -ENOMEM;

    - if (dev->phydev && !ops->get_ethtool_phy_stats) {
    - ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
    - if (ret < 0)
    - return ret;
    + if (n_stats) {
    + data = vzalloc(array_size(n_stats, sizeof(u64)));
    + if (!data)
    + return -ENOMEM;
    +
    + if (dev->phydev && !ops->get_ethtool_phy_stats) {
    + ret = phy_ethtool_get_stats(dev->phydev, &stats, data);
    + if (ret < 0)
    + goto out;
    + } else {
    + ops->get_ethtool_phy_stats(dev, &stats, data);
    + }
    } else {
    - ops->get_ethtool_phy_stats(dev, &stats, data);
    + data = NULL;
    }

    ret = -EFAULT;
    --
    2.19.1


    \
     
     \ /
      Last update: 2019-04-15 21:27    [W:4.129 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site