lkml.org 
[lkml]   [2018]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 094/114] net: socket: fix a missing-check bug
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Wenwen Wang <wang6495@umn.edu>

    [ Upstream commit b6168562c8ce2bd5a30e213021650422e08764dc ]

    In ethtool_ioctl(), the ioctl command 'ethcmd' is checked through a switch
    statement to see whether it is necessary to pre-process the ethtool
    structure, because, as mentioned in the comment, the structure
    ethtool_rxnfc is defined with padding. If yes, a user-space buffer 'rxnfc'
    is allocated through compat_alloc_user_space(). One thing to note here is
    that, if 'ethcmd' is ETHTOOL_GRXCLSRLALL, the size of the buffer 'rxnfc' is
    partially determined by 'rule_cnt', which is actually acquired from the
    user-space buffer 'compat_rxnfc', i.e., 'compat_rxnfc->rule_cnt', through
    get_user(). After 'rxnfc' is allocated, the data in the original user-space
    buffer 'compat_rxnfc' is then copied to 'rxnfc' through copy_in_user(),
    including the 'rule_cnt' field. However, after this copy, no check is
    re-enforced on 'rxnfc->rule_cnt'. So it is possible that a malicious user
    race to change the value in the 'compat_rxnfc->rule_cnt' between these two
    copies. Through this way, the attacker can bypass the previous check on
    'rule_cnt' and inject malicious data. This can cause undefined behavior of
    the kernel and introduce potential security risk.

    This patch avoids the above issue via copying the value acquired by
    get_user() to 'rxnfc->rule_cn', if 'ethcmd' is ETHTOOL_GRXCLSRLALL.

    Signed-off-by: Wenwen Wang <wang6495@umn.edu>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/socket.c | 11 ++++++++---
    1 file changed, 8 insertions(+), 3 deletions(-)

    --- a/net/socket.c
    +++ b/net/socket.c
    @@ -2760,9 +2760,14 @@ static int ethtool_ioctl(struct net *net
    copy_in_user(&rxnfc->fs.ring_cookie,
    &compat_rxnfc->fs.ring_cookie,
    (void __user *)(&rxnfc->fs.location + 1) -
    - (void __user *)&rxnfc->fs.ring_cookie) ||
    - copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt,
    - sizeof(rxnfc->rule_cnt)))
    + (void __user *)&rxnfc->fs.ring_cookie))
    + return -EFAULT;
    + if (ethcmd == ETHTOOL_GRXCLSRLALL) {
    + if (put_user(rule_cnt, &rxnfc->rule_cnt))
    + return -EFAULT;
    + } else if (copy_in_user(&rxnfc->rule_cnt,
    + &compat_rxnfc->rule_cnt,
    + sizeof(rxnfc->rule_cnt)))
    return -EFAULT;
    }


    \
     
     \ /
      Last update: 2018-11-08 23:30    [W:3.299 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site