summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wheeler <git@linux.ewheeler.net>2016-02-26 17:33:56 -0500
committerJens Axboe <axboe@fb.com>2016-03-08 11:19:08 -0500
commit9b299728ed777428b3908ac72ace5f8f84b97789 (patch)
tree5320279c9809787d11a8c735b4173b2c19374292
parent07cc6ef8edc47f8b4fc1e276d31127a0a5863d4d (diff)
bcache: cleaned up error handling around register_cache()
Fix null pointer dereference by changing register_cache() to return an int instead of being void. This allows it to return -ENOMEM or -ENODEV and enables upper layers to handle the OOM case without NULL pointer issues. See this thread: http://thread.gmane.org/gmane.linux.kernel.bcache.devel/3521 Fixes this error: gargamel:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register bcache: register_cache() error opening sdh2: cannot allocate memory BUG: unable to handle kernel NULL pointer dereference at 00000000000009b8 IP: [<ffffffffc05a7e8d>] cache_set_flush+0x102/0x15c [bcache] PGD 120dff067 PUD 1119a3067 PMD 0 Oops: 0000 [#1] SMP Modules linked in: veth ip6table_filter ip6_tables (...) CPU: 4 PID: 3371 Comm: kworker/4:3 Not tainted 4.4.2-amd64-i915-volpreempt-20160213bc1 #3 Hardware name: System manufacturer System Product Name/P8H67-M PRO, BIOS 3904 04/27/2013 Workqueue: events cache_set_flush [bcache] task: ffff88020d5dc280 ti: ffff88020b6f8000 task.ti: ffff88020b6f8000 RIP: 0010:[<ffffffffc05a7e8d>] [<ffffffffc05a7e8d>] cache_set_flush+0x102/0x15c [bcache] Signed-off-by: Eric Wheeler <bcache@linux.ewheeler.net> Tested-by: Marc MERLIN <marc@merlins.org> Cc: <stable@vger.kernel.org>
-rw-r--r--drivers/md/bcache/super.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index b411c73bfeb3..6b07a0c8c729 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1835,11 +1835,12 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca)
1835 return 0; 1835 return 0;
1836} 1836}
1837 1837
1838static void register_cache(struct cache_sb *sb, struct page *sb_page, 1838static int register_cache(struct cache_sb *sb, struct page *sb_page,
1839 struct block_device *bdev, struct cache *ca) 1839 struct block_device *bdev, struct cache *ca)
1840{ 1840{
1841 char name[BDEVNAME_SIZE]; 1841 char name[BDEVNAME_SIZE];
1842 const char *err = "cannot allocate memory"; 1842 const char *err = NULL;
1843 int ret = 0;
1843 1844
1844 memcpy(&ca->sb, sb, sizeof(struct cache_sb)); 1845 memcpy(&ca->sb, sb, sizeof(struct cache_sb));
1845 ca->bdev = bdev; 1846 ca->bdev = bdev;
@@ -1854,27 +1855,35 @@ static void register_cache(struct cache_sb *sb, struct page *sb_page,
1854 if (blk_queue_discard(bdev_get_queue(ca->bdev))) 1855 if (blk_queue_discard(bdev_get_queue(ca->bdev)))
1855 ca->discard = CACHE_DISCARD(&ca->sb); 1856 ca->discard = CACHE_DISCARD(&ca->sb);
1856 1857
1857 if (cache_alloc(sb, ca) != 0) 1858 ret = cache_alloc(sb, ca);
1859 if (ret != 0)
1858 goto err; 1860 goto err;
1859 1861
1860 err = "error creating kobject"; 1862 if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {
1861 if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) 1863 err = "error calling kobject_add";
1862 goto err; 1864 ret = -ENOMEM;
1865 goto out;
1866 }
1863 1867
1864 mutex_lock(&bch_register_lock); 1868 mutex_lock(&bch_register_lock);
1865 err = register_cache_set(ca); 1869 err = register_cache_set(ca);
1866 mutex_unlock(&bch_register_lock); 1870 mutex_unlock(&bch_register_lock);
1867 1871
1868 if (err) 1872 if (err) {
1869 goto err; 1873 ret = -ENODEV;
1874 goto out;
1875 }
1870 1876
1871 pr_info("registered cache device %s", bdevname(bdev, name)); 1877 pr_info("registered cache device %s", bdevname(bdev, name));
1878
1872out: 1879out:
1873 kobject_put(&ca->kobj); 1880 kobject_put(&ca->kobj);
1874 return; 1881
1875err: 1882err:
1876 pr_notice("error opening %s: %s", bdevname(bdev, name), err); 1883 if (err)
1877 goto out; 1884 pr_notice("error opening %s: %s", bdevname(bdev, name), err);
1885
1886 return ret;
1878} 1887}
1879 1888
1880/* Global interfaces/init */ 1889/* Global interfaces/init */
@@ -1972,7 +1981,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
1972 if (!ca) 1981 if (!ca)
1973 goto err_close; 1982 goto err_close;
1974 1983
1975 register_cache(sb, sb_page, bdev, ca); 1984 if (register_cache(sb, sb_page, bdev, ca) != 0)
1985 goto err_close;
1976 } 1986 }
1977out: 1987out:
1978 if (sb_page) 1988 if (sb_page)