diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2020-04-30 12:16:38 +0300 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2020-05-28 12:21:03 +0300 |
commit | a94a59f43749b4f8cd81b8be87c95f9ef898d19d (patch) | |
tree | cd11b10a7607a3683294c22d91ece320d1861e1c /drivers/mmc/core/sdio.c | |
parent | f04086c225da11ad16d7f9a2fbca6483ab16dded (diff) | |
download | linux-a94a59f43749b4f8cd81b8be87c95f9ef898d19d.tar.xz |
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
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r-- | drivers/mmc/core/sdio.c | 58 |
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index d35679e6e6aa..20eed28ea60d 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -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; } |