lkml.org 
[lkml]   [2019]   [Aug]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 138/157] floppy: fix div-by-zero in setup_format_params
    3.16.72-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Denis Efremov <efremov@ispras.ru>

    commit f3554aeb991214cbfafd17d55e2bfddb50282e32 upstream.

    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: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/block/floppy.c | 5 +++++
    1 file changed, 5 insertions(+)

    --- a/drivers/block/floppy.c
    +++ b/drivers/block/floppy.c
    @@ -2113,6 +2113,9 @@ static void setup_format_params(int trac
    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;

    @@ -3235,6 +3238,8 @@ static int set_geometry(unsigned int cmd
    /* 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)
    \
     
     \ /
      Last update: 2019-08-10 22:49    [W:3.792 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site