mmc: sdio: Fix several potential memory leaks in mmc_sdio_init_card()
Over the years, the code in mmc_sdio_init_card() has grown to become quite messy. Unfortunate this has also lead to that several paths are leaking memory in form of an allocated struct mmc_card, which includes additional data, such as initialized struct device for example. Unfortunate, it's a too complex task find each offending commit. Therefore, this change fixes all memory leaks at once. Cc: <stable@vger.kernel.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20200430091640.455-3-ulf.hansson@linaro.org
This commit is contained in:
parent
f04086c225
commit
a94a59f437
|
@ -584,7 +584,7 @@ try_again:
|
|||
*/
|
||||
err = mmc_send_io_op_cond(host, ocr, &rocr);
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
|
||||
/*
|
||||
* For SPI, enable CRC as appropriate.
|
||||
|
@ -592,17 +592,15 @@ try_again:
|
|||
if (mmc_host_is_spi(host)) {
|
||||
err = mmc_spi_set_crc(host, use_spi_crc);
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate card structure.
|
||||
*/
|
||||
card = mmc_alloc_card(host, NULL);
|
||||
if (IS_ERR(card)) {
|
||||
err = PTR_ERR(card);
|
||||
goto err;
|
||||
}
|
||||
if (IS_ERR(card))
|
||||
return PTR_ERR(card);
|
||||
|
||||
if ((rocr & R4_MEMORY_PRESENT) &&
|
||||
mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
|
||||
|
@ -610,19 +608,15 @@ try_again:
|
|||
|
||||
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
|
||||
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
|
||||
mmc_remove_card(card);
|
||||
pr_debug("%s: Perhaps the card was replaced\n",
|
||||
mmc_hostname(host));
|
||||
return -ENOENT;
|
||||
err = -ENOENT;
|
||||
goto mismatch;
|
||||
}
|
||||
} else {
|
||||
card->type = MMC_TYPE_SDIO;
|
||||
|
||||
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
|
||||
mmc_remove_card(card);
|
||||
pr_debug("%s: Perhaps the card was replaced\n",
|
||||
mmc_hostname(host));
|
||||
return -ENOENT;
|
||||
err = -ENOENT;
|
||||
goto mismatch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,7 +671,7 @@ try_again:
|
|||
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
|
||||
err = mmc_sd_get_csd(host, card);
|
||||
if (err)
|
||||
return err;
|
||||
goto remove;
|
||||
|
||||
mmc_decode_cid(card);
|
||||
}
|
||||
|
@ -704,7 +698,12 @@ try_again:
|
|||
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
|
||||
}
|
||||
|
||||
goto finish;
|
||||
if (oldcard)
|
||||
mmc_remove_card(card);
|
||||
else
|
||||
host->card = card;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -730,16 +729,14 @@ try_again:
|
|||
goto remove;
|
||||
|
||||
if (oldcard) {
|
||||
int same = (card->cis.vendor == oldcard->cis.vendor &&
|
||||
card->cis.device == oldcard->cis.device);
|
||||
mmc_remove_card(card);
|
||||
if (!same) {
|
||||
pr_debug("%s: Perhaps the card was replaced\n",
|
||||
mmc_hostname(host));
|
||||
return -ENOENT;
|
||||
if (card->cis.vendor == oldcard->cis.vendor &&
|
||||
card->cis.device == oldcard->cis.device) {
|
||||
mmc_remove_card(card);
|
||||
card = oldcard;
|
||||
} else {
|
||||
err = -ENOENT;
|
||||
goto mismatch;
|
||||
}
|
||||
|
||||
card = oldcard;
|
||||
}
|
||||
card->ocr = ocr_card;
|
||||
mmc_fixup_device(card, sdio_fixup_methods);
|
||||
|
@ -800,16 +797,15 @@ try_again:
|
|||
err = -EINVAL;
|
||||
goto remove;
|
||||
}
|
||||
finish:
|
||||
if (!oldcard)
|
||||
host->card = card;
|
||||
|
||||
host->card = card;
|
||||
return 0;
|
||||
|
||||
mismatch:
|
||||
pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host));
|
||||
remove:
|
||||
if (!oldcard)
|
||||
if (oldcard != card)
|
||||
mmc_remove_card(card);
|
||||
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue