• Jiri Kosina's avatar
    floppy: refactor open() flags handling · 09954bad
    Jiri Kosina authored
    In case /dev/fdX is open with O_NDELAY / O_NONBLOCK, floppy_open() immediately
    succeeds, without performing any further media / controller preparations.
    That's "correct" wrt. the NODELAY flag, but is hardly correct wrt. the rest
    of the floppy driver, that is not really O_NONBLOCK ready, at all. Therefore
    it's not too surprising, that subsequent attempts to work with the
    filedescriptor produce bad results. Namely, syzkaller tool has been able
    to livelock mmap() on the returned fd to keep waiting on the page unlock
    bit forever.
    
    Quite frankly, I have trouble defining what non-blocking behavior would be for
    floppies. Is waiting ages for the driver to actually succeed reading a sector
    blocking operation? Is waiting for drive motor to start blocking operation? How
    about in case of virtualized floppies?
    
    One option would be returning EWOULDBLOCK in case O_NDLEAY / O_NONBLOCK is
    being passed to open(). That has a theoretical potential of breaking some
    arcane and archaic userspace though.
    
    Let's take a more conservative aproach, and accept the O_NDLEAY flag, and let
    the driver behave as usual.
    
    While at it, clean up a bit handling of !(mode & (FMODE_READ|FMODE_WRITE))
    case and return EINVAL instead of succeeding as well.
    
    Spotted by syzkaller tool.
    Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Tested-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    09954bad
floppy.c 117 KB