mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 15:13:52 +00:00
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);
|
err = mmc_send_io_op_cond(host, ocr, &rocr);
|
||||||
if (err)
|
if (err)
|
||||||
goto err;
|
return err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For SPI, enable CRC as appropriate.
|
* For SPI, enable CRC as appropriate.
|
||||||
@ -592,17 +592,15 @@ try_again:
|
|||||||
if (mmc_host_is_spi(host)) {
|
if (mmc_host_is_spi(host)) {
|
||||||
err = mmc_spi_set_crc(host, use_spi_crc);
|
err = mmc_spi_set_crc(host, use_spi_crc);
|
||||||
if (err)
|
if (err)
|
||||||
goto err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate card structure.
|
* Allocate card structure.
|
||||||
*/
|
*/
|
||||||
card = mmc_alloc_card(host, NULL);
|
card = mmc_alloc_card(host, NULL);
|
||||||
if (IS_ERR(card)) {
|
if (IS_ERR(card))
|
||||||
err = PTR_ERR(card);
|
return PTR_ERR(card);
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rocr & R4_MEMORY_PRESENT) &&
|
if ((rocr & R4_MEMORY_PRESENT) &&
|
||||||
mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
|
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 ||
|
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
|
||||||
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
|
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
|
||||||
mmc_remove_card(card);
|
err = -ENOENT;
|
||||||
pr_debug("%s: Perhaps the card was replaced\n",
|
goto mismatch;
|
||||||
mmc_hostname(host));
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
card->type = MMC_TYPE_SDIO;
|
card->type = MMC_TYPE_SDIO;
|
||||||
|
|
||||||
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
|
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
|
||||||
mmc_remove_card(card);
|
err = -ENOENT;
|
||||||
pr_debug("%s: Perhaps the card was replaced\n",
|
goto mismatch;
|
||||||
mmc_hostname(host));
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,7 +671,7 @@ try_again:
|
|||||||
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
|
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
|
||||||
err = mmc_sd_get_csd(host, card);
|
err = mmc_sd_get_csd(host, card);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto remove;
|
||||||
|
|
||||||
mmc_decode_cid(card);
|
mmc_decode_cid(card);
|
||||||
}
|
}
|
||||||
@ -704,7 +698,12 @@ try_again:
|
|||||||
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
|
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;
|
goto remove;
|
||||||
|
|
||||||
if (oldcard) {
|
if (oldcard) {
|
||||||
int same = (card->cis.vendor == oldcard->cis.vendor &&
|
if (card->cis.vendor == oldcard->cis.vendor &&
|
||||||
card->cis.device == oldcard->cis.device);
|
card->cis.device == oldcard->cis.device) {
|
||||||
mmc_remove_card(card);
|
mmc_remove_card(card);
|
||||||
if (!same) {
|
card = oldcard;
|
||||||
pr_debug("%s: Perhaps the card was replaced\n",
|
} else {
|
||||||
mmc_hostname(host));
|
err = -ENOENT;
|
||||||
return -ENOENT;
|
goto mismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
card = oldcard;
|
|
||||||
}
|
}
|
||||||
card->ocr = ocr_card;
|
card->ocr = ocr_card;
|
||||||
mmc_fixup_device(card, sdio_fixup_methods);
|
mmc_fixup_device(card, sdio_fixup_methods);
|
||||||
@ -800,16 +797,15 @@ try_again:
|
|||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto remove;
|
goto remove;
|
||||||
}
|
}
|
||||||
finish:
|
|
||||||
if (!oldcard)
|
host->card = card;
|
||||||
host->card = card;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
mismatch:
|
||||||
|
pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host));
|
||||||
remove:
|
remove:
|
||||||
if (!oldcard)
|
if (oldcard != card)
|
||||||
mmc_remove_card(card);
|
mmc_remove_card(card);
|
||||||
|
|
||||||
err:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user