lkml.org 
[lkml]   [2019]   [Jul]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.2 250/413] floppy: fix invalid pointer dereference in drive_name
    Date
    [ Upstream commit 9b04609b784027968348796a18f601aed9db3789 ]

    This fixes the invalid pointer dereference in the drive_name function of
    the floppy driver.

    The native_format field of the struct floppy_drive_params is used as
    floppy_type array index in the drive_name function. Thus, the field
    should be checked the same way as the autodetect field.

    To trigger the bug, one could use a value out of range and set the drive
    parameters with the FDSETDRVPRM ioctl. Next, FDGETDRVTYP ioctl should
    be used to call the drive_name. A floppy disk is not required to be
    inserted.

    CAP_SYS_ADMIN is required to call FDSETDRVPRM.

    The patch adds the check for a value of the native_format field to be in
    the '0 <= x < ARRAY_SIZE(floppy_type)' range of the floppy_type array
    indices.

    The bug was found by syzkaller.

    Signed-off-by: Denis Efremov <efremov@ispras.ru>
    Tested-by: Willy Tarreau <w@1wt.eu>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/block/floppy.c | 11 ++++++++---
    1 file changed, 8 insertions(+), 3 deletions(-)

    diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
    index b70d6e103a57..671a0ae434b4 100644
    --- a/drivers/block/floppy.c
    +++ b/drivers/block/floppy.c
    @@ -3380,7 +3380,8 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
    return 0;
    }

    -static bool valid_floppy_drive_params(const short autodetect[8])
    +static bool valid_floppy_drive_params(const short autodetect[8],
    + int native_format)
    {
    size_t floppy_type_size = ARRAY_SIZE(floppy_type);
    size_t i = 0;
    @@ -3391,6 +3392,9 @@ static bool valid_floppy_drive_params(const short autodetect[8])
    return false;
    }

    + if (native_format < 0 || native_format >= floppy_type_size)
    + return false;
    +
    return true;
    }

    @@ -3520,7 +3524,8 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
    SUPBOUND(size, strlen((const char *)outparam) + 1);
    break;
    case FDSETDRVPRM:
    - if (!valid_floppy_drive_params(inparam.dp.autodetect))
    + if (!valid_floppy_drive_params(inparam.dp.autodetect,
    + inparam.dp.native_format))
    return -EINVAL;
    *UDP = inparam.dp;
    break;
    @@ -3719,7 +3724,7 @@ static int compat_setdrvprm(int drive,
    return -EPERM;
    if (copy_from_user(&v, arg, sizeof(struct compat_floppy_drive_params)))
    return -EFAULT;
    - if (!valid_floppy_drive_params(v.autodetect))
    + if (!valid_floppy_drive_params(v.autodetect, v.native_format))
    return -EINVAL;
    mutex_lock(&floppy_mutex);
    UDP->cmos = v.cmos;
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-07-24 21:40    [W:4.094 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site