• Jan Kara's avatar
    bdi: Fix use-after-free in wb_congested_put() · df23de55
    Jan Kara authored
    bdi_writeback_congested structures get created for each blkcg and bdi
    regardless whether bdi is registered or not. When they are created in
    unregistered bdi and the request queue (and thus bdi) is then destroyed
    while blkg still holds reference to bdi_writeback_congested structure,
    this structure will be referencing freed bdi and last wb_congested_put()
    will try to remove the structure from already freed bdi.
    
    With commit 165a5e22 "block: Move bdi_unregister() to
    del_gendisk()", SCSI started to destroy bdis without calling
    bdi_unregister() first (previously it was calling bdi_unregister() even
    for unregistered bdis) and thus the code detaching
    bdi_writeback_congested in cgwb_bdi_destroy() was not triggered and we
    started hitting this use-after-free bug. It is enough to boot a KVM
    instance with virtio-scsi device to trigger this behavior.
    
    Fix the problem by detaching bdi_writeback_congested structures in
    bdi_exit() instead of bdi_unregister(). This is also more logical as
    they can get attached to bdi regardless whether it ever got registered
    or not.
    
    Fixes: 165a5e22Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Tested-by: default avatarOmar Sandoval <osandov@fb.com>
    Signed-off-by: default avatarJens Axboe <axboe@fb.com>
    df23de55
backing-dev.c 27.3 KB