lkml.org 
[lkml]   [2019]   [Jul]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 160/271] floppy: fix div-by-zero in setup_format_params
    Date
    [ Upstream commit f3554aeb991214cbfafd17d55e2bfddb50282e32 ]

    This fixes a divide by zero error in the setup_format_params function of
    the floppy driver.

    Two consecutive ioctls can trigger the bug: The first one should set the
    drive geometry with such .sect and .rate values for the F_SECT_PER_TRACK
    to become zero. Next, the floppy format operation should be called.

    A floppy disk is not required to be inserted. An unprivileged user
    could trigger the bug if the device is accessible.

    The patch checks F_SECT_PER_TRACK for a non-zero value in the
    set_geometry function. The proper check should involve a reasonable
    upper limit for the .sect and .rate fields, but it could change the
    UAPI.

    The patch also checks F_SECT_PER_TRACK in the setup_format_params, and
    cancels the formatting operation in case of zero.

    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 | 5 +++++
    1 file changed, 5 insertions(+)

    diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
    index a8de56f1936d..b1425b218606 100644
    --- a/drivers/block/floppy.c
    +++ b/drivers/block/floppy.c
    @@ -2119,6 +2119,9 @@ static void setup_format_params(int track)
    raw_cmd->kernel_data = floppy_track_buffer;
    raw_cmd->length = 4 * F_SECT_PER_TRACK;

    + if (!F_SECT_PER_TRACK)
    + return;
    +
    /* allow for about 30ms for data transport per track */
    head_shift = (F_SECT_PER_TRACK + 5) / 6;

    @@ -3243,6 +3246,8 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g,
    /* sanity checking for parameters. */
    if (g->sect <= 0 ||
    g->head <= 0 ||
    + /* check for zero in F_SECT_PER_TRACK */
    + (unsigned char)((g->sect << 2) >> FD_SIZECODE(g)) == 0 ||
    g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
    /* check if reserved bits are set */
    (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-07-25 07:44    [W:6.152 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site