summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinmao Li <lilinmao@kylinos.cn>2026-07-17 09:24:33 +0800
committerMark Brown <broonie@kernel.org>2026-07-19 21:10:36 +0100
commit2aaa41cf974f83a6fb105422bac4e2f107150774 (patch)
treeeaa454d5c28b0255b5559518a7ef748a3fd66d2d
parentc89b22faa9ba8ffaed2c696a360528844b5ba069 (diff)
ASoC: meson: Keep link pointers valid on realloc failure
meson_card_reallocate_links() grows the DAI link and private data arrays with two consecutive krealloc() calls and updates the owner pointers only after both calls have succeeded. A successful krealloc() may move the data: it frees the old block and returns a new one. When that happens for the link array and the second krealloc() then fails, card->dai_link still points to the block that krealloc() already freed, and the error path frees the new block too. The probe error path then calls meson_card_clean_references(), which dereferences card->dai_link and kfree()s it again, resulting in a use-after-free and a double free. Commit card->dai_link and card->num_links right after the first krealloc() succeeds, so the pointer always refers to a valid allocation that meson_card_clean_references() can walk and free. krealloc() with __GFP_ZERO zero-initializes the added entries, so walking them on the error path is safe. With both failure paths reduced to a plain return, drop the goto labels and the error message. Fixes: 7864a79f37b5 ("ASoC: meson: add axg sound card support") Signed-off-by: Linmao Li <lilinmao@kylinos.cn> Reviewed-by: Jerome Brunet <jbrunet@baylibre.com> Link: https://patch.msgid.link/20260717012433.1432285-1-lilinmao@kylinos.cn Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/meson/meson-card-utils.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/sound/soc/meson/meson-card-utils.c b/sound/soc/meson/meson-card-utils.c
index cdb759b466ad..8617a4661a33 100644
--- a/sound/soc/meson/meson-card-utils.c
+++ b/sound/soc/meson/meson-card-utils.c
@@ -50,25 +50,20 @@ int meson_card_reallocate_links(struct snd_soc_card *card,
num_links * sizeof(*priv->card.dai_link),
GFP_KERNEL | __GFP_ZERO);
if (!links)
- goto err_links;
+ return -ENOMEM;
+
+ priv->card.dai_link = links;
+ priv->card.num_links = num_links;
ldata = krealloc(priv->link_data,
num_links * sizeof(*priv->link_data),
GFP_KERNEL | __GFP_ZERO);
+ /* meson_card_clean_references() will free the links on this error path */
if (!ldata)
- goto err_ldata;
+ return -ENOMEM;
- priv->card.dai_link = links;
priv->link_data = ldata;
- priv->card.num_links = num_links;
return 0;
-
-err_ldata:
- kfree(links);
-err_links:
- dev_err(priv->card.dev, "failed to allocate links\n");
- return -ENOMEM;
-
}
EXPORT_SYMBOL_GPL(meson_card_reallocate_links);