aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2009-04-02 14:55:35 -0400
committerAlasdair G Kergon <agk@redhat.com>2009-04-02 14:55:35 -0400
commita32079ce17899192a7b98a42753be467605a8b2f (patch)
tree116fefba16427c16cb792e218889aa971eab755b /drivers/md
parent1e302a929e2da6e8448e2058e4b07b07252b57fe (diff)
dm snapshot: persistent fix dtr cleanup
The persistent exception store destructor does not properly account for all conditions in which it can be called. If it is called after 'ctr' but before 'read_metadata' (e.g. if something else in 'snapshot_ctr' fails) then it will attempt to free areas of memory that haven't been allocated yet. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-snap-persistent.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 1799205cd945..e75c6dd76a9a 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -162,9 +162,12 @@ static int alloc_area(struct pstore *ps)
162 162
163static void free_area(struct pstore *ps) 163static void free_area(struct pstore *ps)
164{ 164{
165 vfree(ps->area); 165 if (ps->area)
166 vfree(ps->area);
166 ps->area = NULL; 167 ps->area = NULL;
167 vfree(ps->zero_area); 168
169 if (ps->zero_area)
170 vfree(ps->zero_area);
168 ps->zero_area = NULL; 171 ps->zero_area = NULL;
169} 172}
170 173
@@ -482,9 +485,16 @@ static void persistent_dtr(struct dm_exception_store *store)
482 struct pstore *ps = get_info(store); 485 struct pstore *ps = get_info(store);
483 486
484 destroy_workqueue(ps->metadata_wq); 487 destroy_workqueue(ps->metadata_wq);
485 dm_io_client_destroy(ps->io_client); 488
486 vfree(ps->callbacks); 489 /* Created in read_header */
490 if (ps->io_client)
491 dm_io_client_destroy(ps->io_client);
487 free_area(ps); 492 free_area(ps);
493
494 /* Allocated in persistent_read_metadata */
495 if (ps->callbacks)
496 vfree(ps->callbacks);
497
488 kfree(ps); 498 kfree(ps);
489} 499}
490 500
@@ -661,7 +671,7 @@ static int persistent_ctr(struct dm_exception_store *store,
661 struct pstore *ps; 671 struct pstore *ps;
662 672
663 /* allocate the pstore */ 673 /* allocate the pstore */
664 ps = kmalloc(sizeof(*ps), GFP_KERNEL); 674 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
665 if (!ps) 675 if (!ps)
666 return -ENOMEM; 676 return -ENOMEM;
667 677