diff options
author | Slava Pestov <sp@daterainc.com> | 2014-06-19 18:05:59 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-08-04 18:23:04 -0400 |
commit | c9a78332b42cbdcdd386a95192a716b67d1711a4 (patch) | |
tree | 425e035b57317fa9730d717352cee12ab2c8bccd /drivers/md | |
parent | bf0c55c986540483c34ca640f2eef4c3314388b1 (diff) |
bcache: fix memory corruption in init error path
If register_cache_set() failed, we would touch ca->set after
it had already been freed. Also, fix an assertion to catch
this.
Change-Id: I748e5f5b223e2d9b2602075dec2f997cced2394d
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/super.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 72fbaf79b0c8..12ad381bdbab 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -1356,8 +1356,11 @@ static void cache_set_free(struct closure *cl) | |||
1356 | bch_journal_free(c); | 1356 | bch_journal_free(c); |
1357 | 1357 | ||
1358 | for_each_cache(ca, c, i) | 1358 | for_each_cache(ca, c, i) |
1359 | if (ca) | 1359 | if (ca) { |
1360 | ca->set = NULL; | ||
1361 | c->cache[ca->sb.nr_this_dev] = NULL; | ||
1360 | kobject_put(&ca->kobj); | 1362 | kobject_put(&ca->kobj); |
1363 | } | ||
1361 | 1364 | ||
1362 | bch_bset_sort_state_free(&c->sort); | 1365 | bch_bset_sort_state_free(&c->sort); |
1363 | free_pages((unsigned long) c->uuids, ilog2(bucket_pages(c))); | 1366 | free_pages((unsigned long) c->uuids, ilog2(bucket_pages(c))); |
@@ -1794,8 +1797,10 @@ void bch_cache_release(struct kobject *kobj) | |||
1794 | struct cache *ca = container_of(kobj, struct cache, kobj); | 1797 | struct cache *ca = container_of(kobj, struct cache, kobj); |
1795 | unsigned i; | 1798 | unsigned i; |
1796 | 1799 | ||
1797 | if (ca->set) | 1800 | if (ca->set) { |
1801 | BUG_ON(ca->set->cache[ca->sb.nr_this_dev] != ca); | ||
1798 | ca->set->cache[ca->sb.nr_this_dev] = NULL; | 1802 | ca->set->cache[ca->sb.nr_this_dev] = NULL; |
1803 | } | ||
1799 | 1804 | ||
1800 | bio_split_pool_free(&ca->bio_split_hook); | 1805 | bio_split_pool_free(&ca->bio_split_hook); |
1801 | 1806 | ||
@@ -1858,7 +1863,7 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca) | |||
1858 | } | 1863 | } |
1859 | 1864 | ||
1860 | static void register_cache(struct cache_sb *sb, struct page *sb_page, | 1865 | static void register_cache(struct cache_sb *sb, struct page *sb_page, |
1861 | struct block_device *bdev, struct cache *ca) | 1866 | struct block_device *bdev, struct cache *ca) |
1862 | { | 1867 | { |
1863 | char name[BDEVNAME_SIZE]; | 1868 | char name[BDEVNAME_SIZE]; |
1864 | const char *err = "cannot allocate memory"; | 1869 | const char *err = "cannot allocate memory"; |