Skip to content

Commit 0e65554

Browse files
Eric Wheelersashalevin
authored andcommitted
bcache: cleaned up error handling around register_cache()
[ Upstream commit 9b29972 ] 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 <[email protected]> Tested-by: Marc MERLIN <[email protected]> Cc: <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 7269554 commit 0e65554

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

drivers/md/bcache/super.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,11 +1869,12 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca)
18691869
return 0;
18701870
}
18711871

1872-
static void register_cache(struct cache_sb *sb, struct page *sb_page,
1872+
static int register_cache(struct cache_sb *sb, struct page *sb_page,
18731873
struct block_device *bdev, struct cache *ca)
18741874
{
18751875
char name[BDEVNAME_SIZE];
1876-
const char *err = "cannot allocate memory";
1876+
const char *err = NULL;
1877+
int ret = 0;
18771878

18781879
memcpy(&ca->sb, sb, sizeof(struct cache_sb));
18791880
ca->bdev = bdev;
@@ -1888,27 +1889,35 @@ static void register_cache(struct cache_sb *sb, struct page *sb_page,
18881889
if (blk_queue_discard(bdev_get_queue(ca->bdev)))
18891890
ca->discard = CACHE_DISCARD(&ca->sb);
18901891

1891-
if (cache_alloc(sb, ca) != 0)
1892+
ret = cache_alloc(sb, ca);
1893+
if (ret != 0)
18921894
goto err;
18931895

1894-
err = "error creating kobject";
1895-
if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache"))
1896-
goto err;
1896+
if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {
1897+
err = "error calling kobject_add";
1898+
ret = -ENOMEM;
1899+
goto out;
1900+
}
18971901

18981902
mutex_lock(&bch_register_lock);
18991903
err = register_cache_set(ca);
19001904
mutex_unlock(&bch_register_lock);
19011905

1902-
if (err)
1903-
goto err;
1906+
if (err) {
1907+
ret = -ENODEV;
1908+
goto out;
1909+
}
19041910

19051911
pr_info("registered cache device %s", bdevname(bdev, name));
1912+
19061913
out:
19071914
kobject_put(&ca->kobj);
1908-
return;
1915+
19091916
err:
1910-
pr_notice("error opening %s: %s", bdevname(bdev, name), err);
1911-
goto out;
1917+
if (err)
1918+
pr_notice("error opening %s: %s", bdevname(bdev, name), err);
1919+
1920+
return ret;
19121921
}
19131922

19141923
/* Global interfaces/init */
@@ -2006,7 +2015,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
20062015
if (!ca)
20072016
goto err_close;
20082017

2009-
register_cache(sb, sb_page, bdev, ca);
2018+
if (register_cache(sb, sb_page, bdev, ca) != 0)
2019+
goto err_close;
20102020
}
20112021
out:
20122022
if (sb_page)

0 commit comments

Comments
 (0)