• Tony Battersby's avatar
    [SCSI] sg: fix races during device removal · c6517b79
    Tony Battersby authored
    sg has the following problems related to device removal:
    
    * opening a sg fd races with removing a device
    * closing a sg fd races with removing a device
    * /proc/scsi/sg/* access races with removing a device
    * command completion races with removing a device
    * command completion races with closing a sg fd
    * can rmmod sg with active commands
    
    These problems can cause kernel oopses, memory-use-after-free, or
    double-free errors.  This patch fixes these problems by using krefs
    to manage the lifetime of sg_device and sg_fd.
    
    Each command submitted to the midlevel holds a reference to sg_fd
    until the completion callback.  This ensures that sg_fd doesn't go
    away if the fd is closed with commands still outstanding.
    
    sg_fd gets the reference of sg_device (with scsi_device) and also
    makes sure that the sg module doesn't go away.
    
    /proc/scsi/sg/* functions don't play nicely with krefs because they
    give information about sg_fds which have been closed but not yet
    freed due to still having outstanding commands and sg_devices which
    have been removed but not yet freed due to still being referenced
    by one or more sg_fds.  To deal with this safely without removing
    functionality, /proc functions now access sg_device and sg_fd while
    holding a lock instead of using kref_get()/kref_put().
    Signed-off-by: default avatarTony Battersby <tonyb@cybernetics.com>
    Acked-by: default avatarDouglas Gilbert <dgilbert@interlog.com>
    Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
    c6517b79
sg.c 69.3 KB