lkml.org 
[lkml]   [2020]   [Jan]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 020/104] airo: Add missing CAP_NET_ADMIN check in AIROOLDIOCTL/SIOCDEVPRIVATE
    Date
    From: Michael Ellerman <mpe@ellerman.id.au>

    [ Upstream commit 78f7a7566f5eb59321e99b55a6fdb16ea05b37d1 ]

    The driver for Cisco Aironet 4500 and 4800 series cards (airo.c),
    implements AIROOLDIOCTL/SIOCDEVPRIVATE in airo_ioctl().

    The ioctl handler copies an aironet_ioctl struct from userspace, which
    includes a command. Some of the commands are handled in readrids(),
    where the user controlled command is converted into a driver-internal
    value called "ridcode".

    There are two command values, AIROGWEPKTMP and AIROGWEPKNV, which
    correspond to ridcode values of RID_WEP_TEMP and RID_WEP_PERM
    respectively. These commands both have checks that the user has
    CAP_NET_ADMIN, with the comment that "Only super-user can read WEP
    keys", otherwise they return -EPERM.

    However there is another command value, AIRORRID, that lets the user
    specify the ridcode value directly, with no other checks. This means
    the user can bypass the CAP_NET_ADMIN check on AIROGWEPKTMP and
    AIROGWEPKNV.

    Fix it by moving the CAP_NET_ADMIN check out of the command handling
    and instead do it later based on the ridcode. That way regardless of
    whether the ridcode is set via AIROGWEPKTMP or AIROGWEPKNV, or passed
    in using AIRORID, we always do the CAP_NET_ADMIN check.

    Found by Ilja by code inspection, not tested as I don't have the
    required hardware.

    Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/wireless/cisco/airo.c | 18 ++++++++----------
    1 file changed, 8 insertions(+), 10 deletions(-)

    --- a/drivers/net/wireless/cisco/airo.c
    +++ b/drivers/net/wireless/cisco/airo.c
    @@ -7790,16 +7790,8 @@ static int readrids(struct net_device *d
    case AIROGVLIST: ridcode = RID_APLIST; break;
    case AIROGDRVNAM: ridcode = RID_DRVNAME; break;
    case AIROGEHTENC: ridcode = RID_ETHERENCAP; break;
    - case AIROGWEPKTMP: ridcode = RID_WEP_TEMP;
    - /* Only super-user can read WEP keys */
    - if (!capable(CAP_NET_ADMIN))
    - return -EPERM;
    - break;
    - case AIROGWEPKNV: ridcode = RID_WEP_PERM;
    - /* Only super-user can read WEP keys */
    - if (!capable(CAP_NET_ADMIN))
    - return -EPERM;
    - break;
    + case AIROGWEPKTMP: ridcode = RID_WEP_TEMP; break;
    + case AIROGWEPKNV: ridcode = RID_WEP_PERM; break;
    case AIROGSTAT: ridcode = RID_STATUS; break;
    case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
    case AIROGSTATSC32: ridcode = RID_STATS; break;
    @@ -7813,6 +7805,12 @@ static int readrids(struct net_device *d
    return -EINVAL;
    }

    + if (ridcode == RID_WEP_TEMP || ridcode == RID_WEP_PERM) {
    + /* Only super-user can read WEP keys */
    + if (!capable(CAP_NET_ADMIN))
    + return -EPERM;
    + }
    +
    if ((iobuf = kzalloc(RIDSIZE, GFP_KERNEL)) == NULL)
    return -ENOMEM;


    \
     
     \ /
      Last update: 2020-01-28 15:49    [W:4.012 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site