Commit b06075a9 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Mike Snitzer

dm: fix use after free crash due to incorrect cleanup sequence

Linux 4.2-rc1 Commit 0f20972f ("dm: factor out a common
cleanup_mapped_device()") moved a common cleanup code to a separate
function.  Unfortunately, that commit incorrectly changed the order of
cleanup, so that it destroys the mapped_device's srcu structure
'io_barrier' before destroying its workqueue.

The function that is executed on the workqueue (dm_wq_work) uses the srcu
structure, thus it may use it after being freed.  That results in a
crash in the LVM test suite's mirror-vgreduce-removemissing.sh test.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Fixes: 0f20972f ("dm: factor out a common cleanup_mapped_device()")
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 621739b0
...@@ -2277,8 +2277,6 @@ static void dm_init_old_md_queue(struct mapped_device *md) ...@@ -2277,8 +2277,6 @@ static void dm_init_old_md_queue(struct mapped_device *md)
static void cleanup_mapped_device(struct mapped_device *md) static void cleanup_mapped_device(struct mapped_device *md)
{ {
cleanup_srcu_struct(&md->io_barrier);
if (md->wq) if (md->wq)
destroy_workqueue(md->wq); destroy_workqueue(md->wq);
if (md->kworker_task) if (md->kworker_task)
...@@ -2290,6 +2288,8 @@ static void cleanup_mapped_device(struct mapped_device *md) ...@@ -2290,6 +2288,8 @@ static void cleanup_mapped_device(struct mapped_device *md)
if (md->bs) if (md->bs)
bioset_free(md->bs); bioset_free(md->bs);
cleanup_srcu_struct(&md->io_barrier);
if (md->disk) { if (md->disk) {
spin_lock(&_minor_lock); spin_lock(&_minor_lock);
md->disk->private_data = NULL; md->disk->private_data = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment