• Ming Lei's avatar
    block: fix use-after-free on cached last_lookup partition · b7d6c303
    Ming Lei authored
    delete_partition() clears the cached last_lookup partition. However the
    .last_lookup cache may be overwritten by one IO path after it is cleared
    from delete_partition(). Then another IO path may use the cached deleting
    partition after hd_struct_free() is called, then use-after-free is triggered
    on the cached partition.
    
    Fixes the issue by the following approach:
    
    1) always get the partition's refcount via hd_struct_try_get() before
    setting .last_lookup
    
    2) move clearing .last_lookup from delete_partition() to hd_struct_free()
    which is the release handle of the partition's percpu-refcount, so that no
    IO path can cache deleteing partition via .last_lookup.
    
    It is one candidate approach of Yufen's patch[1] which adds overhead
    in fast path by indirect lookup which may introduce one extra cacheline
    in IO path. Also this patch relies on percpu-refcount's protection, and
    it is easier to understand and verify.
    
    [1] https://lore.kernel.org/linux-block/20200109013551.GB9655@ming.t460p/T/#tReported-by: default avatarYufen Yu <yuyufen@huawei.com>
    Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@infradead.org>
    Cc: Christoph Hellwig <hch@infradead.org>
    Cc: Hou Tao <houtao1@huawei.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    b7d6c303
genhd.c 55.8 KB