• M
    dm thin: fix use-after-free in metadata_pre_commit_callback · a4a8d286
    Mike Snitzer 提交于
    dm-thin uses struct pool to hold the state of the pool. There may be
    multiple pool_c's pointing to a given pool, each pool_c represents a
    loaded target. pool_c's may be created and destroyed arbitrarily and the
    pool contains a reference count of pool_c's pointing to it.
    
    Since commit 694cfe7f ("dm thin: Flush data device before
    committing metadata") a pointer to pool_c is passed to
    dm_pool_register_pre_commit_callback and this function stores it in
    pmd->pre_commit_context. If this pool_c is freed, but pool is not
    (because there is another pool_c referencing it), we end up in a
    situation where pmd->pre_commit_context structure points to freed
    pool_c. It causes a crash in metadata_pre_commit_callback.
    
    Fix this by moving the dm_pool_register_pre_commit_callback() from
    pool_ctr() to pool_preresume(). This way the in-core thin-pool metadata
    is only ever armed with callback data whose lifetime matches the
    active thin-pool target.
    
    In should be noted that this fix preserves the ability to load a
    thin-pool table that uses a different data block device (that contains
    the same data) -- though it is unclear if that capability is still
    useful and/or needed.
    
    Fixes: 694cfe7f ("dm thin: Flush data device before committing metadata")
    Cc: stable@vger.kernel.org
    Reported-by: NZdenek Kabelac <zkabelac@redhat.com>
    Reported-by: NMikulas Patocka <mpatocka@redhat.com>
    Signed-off-by: NMike Snitzer <snitzer@redhat.com>
    a4a8d286
dm-thin.c 112.4 KB