bsg: fix race of bsg_open and bsg_unregister

The existing implementation allows races between bsg_unregister and
bsg_open paths. bsg_unregister and request_queue cleanup and deletion
may start and complete right after bsg_get_device (in bsg_open path)
retrieves bsg_class_device and releases the mutex. Then bsg_open path
touches freed memory of bsg_class_device and request_queue.

One possible fix is to hold the mutex all the way through bsg_get_device
instead of releasing it after bsg_class_device retrieval.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-Off-By: Anatoliy Glagolev <glagolig@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by Anatoliy Glagolev and committed by Jens Axboe d6c73964 be7f99c5

Changed files
+11 -11
block
+11 -11
block/bsg.c
··· 693 693 struct bsg_device *bd; 694 694 unsigned char buf[32]; 695 695 696 + lockdep_assert_held(&bsg_mutex); 697 + 696 698 if (!blk_get_queue(rq)) 697 699 return ERR_PTR(-ENXIO); 698 700 ··· 709 707 bsg_set_block(bd, file); 710 708 711 709 atomic_set(&bd->ref_count, 1); 712 - mutex_lock(&bsg_mutex); 713 710 hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode))); 714 711 715 712 strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1); 716 713 bsg_dbg(bd, "bound to <%s>, max queue %d\n", 717 714 format_dev_t(buf, inode->i_rdev), bd->max_queue); 718 715 719 - mutex_unlock(&bsg_mutex); 720 716 return bd; 721 717 } 722 718 ··· 722 722 { 723 723 struct bsg_device *bd; 724 724 725 - mutex_lock(&bsg_mutex); 725 + lockdep_assert_held(&bsg_mutex); 726 726 727 727 hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) { 728 728 if (bd->queue == q) { ··· 732 732 } 733 733 bd = NULL; 734 734 found: 735 - mutex_unlock(&bsg_mutex); 736 735 return bd; 737 736 } 738 737 ··· 745 746 */ 746 747 mutex_lock(&bsg_mutex); 747 748 bcd = idr_find(&bsg_minor_idr, iminor(inode)); 748 - mutex_unlock(&bsg_mutex); 749 749 750 - if (!bcd) 751 - return ERR_PTR(-ENODEV); 750 + if (!bcd) { 751 + bd = ERR_PTR(-ENODEV); 752 + goto out_unlock; 753 + } 752 754 753 755 bd = __bsg_get_device(iminor(inode), bcd->queue); 754 - if (bd) 755 - return bd; 756 + if (!bd) 757 + bd = bsg_add_device(inode, bcd->queue, file); 756 758 757 - bd = bsg_add_device(inode, bcd->queue, file); 758 - 759 + out_unlock: 760 + mutex_unlock(&bsg_mutex); 759 761 return bd; 760 762 } 761 763