aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2021-03-03 13:20:49 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2021-03-30 11:42:01 +0200
commit6f1d3247662acef35ef6882528028b4b470baab4 (patch)
tree76b2ca0beab97459acf809fdf5e8125d7125869c /drivers/mmc
parentmmc: block: Simplify logging during probe about added partitions (diff)
downloadlinux-dev-6f1d3247662acef35ef6882528028b4b470baab4.tar.xz
linux-dev-6f1d3247662acef35ef6882528028b4b470baab4.zip
mmc: block: Fix error path in mmc_blk_probe()
Returning zero to indicate success, when we actually have failed to probe is wrong. As a matter of fact, it leads to that mmc_blk_remove() gets called at a card removal and then triggers "NULL pointer dereference" splats. This is because mmc_blk_remove() relies on data structures and pointers to be setup from mmc_blk_probe(), of course. There have been no errors reported about this, which is most likely because mmc_blk_probe() never fails like this. Nevertheless, let's fix the code by propagating the error codes correctly and prevent us from leaking memory by calling also destroy_workqueue() in the error path. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20210303122049.151986-4-ulf.hansson@linaro.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/block.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 39308b35a1fb..02b656305042 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2876,6 +2876,7 @@ static void mmc_blk_remove_debugfs(struct mmc_card *card,
static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md, *part_md;
+ int ret = 0;
/*
* Check that the card supports the command class(es) we need.
@@ -2893,19 +2894,24 @@ static int mmc_blk_probe(struct mmc_card *card)
}
md = mmc_blk_alloc(card);
- if (IS_ERR(md))
- return PTR_ERR(md);
+ if (IS_ERR(md)) {
+ ret = PTR_ERR(md);
+ goto out_free;
+ }
- if (mmc_blk_alloc_parts(card, md))
+ ret = mmc_blk_alloc_parts(card, md);
+ if (ret)
goto out;
dev_set_drvdata(&card->dev, md);
- if (mmc_add_disk(md))
+ ret = mmc_add_disk(md);
+ if (ret)
goto out;
list_for_each_entry(part_md, &md->part, part) {
- if (mmc_add_disk(part_md))
+ ret = mmc_add_disk(part_md);
+ if (ret)
goto out;
}
@@ -2926,10 +2932,12 @@ static int mmc_blk_probe(struct mmc_card *card)
return 0;
- out:
+out:
mmc_blk_remove_parts(card, md);
mmc_blk_remove_req(md);
- return 0;
+out_free:
+ destroy_workqueue(card->complete_wq);
+ return ret;
}
static void mmc_blk_remove(struct mmc_card *card)