Commit 8a473c39 authored by Fred Oh's avatar Fred Oh Committed by Mark Brown

ASoC: Intel: Boards: cml_rt1011_rt5682: use statically define codec config

When the cml_rt1011_rt5682_dailink[].codecs pointer is overridden by
a quirk with a devm allocated structure and the probe is deferred,
in the next probe we will see an use-after-free condition
(verified with KASAN). This can be avoided by using statically allocated
configurations - which simplifies the code quite a bit as well.

KASAN issue fixed.
[   23.301373] cml_rt1011_rt5682 cml_rt1011_rt5682: sof_rt1011_quirk = f
[   23.301875] ==================================================================
[   23.302018] BUG: KASAN: use-after-free in snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682]
[   23.302178] Read of size 8 at addr ffff8881ec6acae0 by task kworker/0:2/105
[   23.302320] CPU: 0 PID: 105 Comm: kworker/0:2 Not tainted 5.7.0-rc7-test+ #3
[   23.302322] Hardware name: Google Helios/Helios, BIOS  01/21/2020
[   23.302329] Workqueue: events deferred_probe_work_func
[   23.302331] Call Trace:
[   23.302339]  dump_stack+0x76/0xa0
[   23.302345]  print_address_description.constprop.0.cold+0xd3/0x43e
[   23.302351]  ? _raw_spin_lock_irqsave+0x7b/0xd0
[   23.302355]  ? _raw_spin_trylock_bh+0xf0/0xf0
[   23.302362]  ? snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682]
[   23.302365]  __kasan_report.cold+0x37/0x86
[   23.302371]  ? snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682]
[   23.302375]  kasan_report+0x38/0x50
[   23.302382]  snd_cml_rt1011_probe+0x23a/0x3d0 [snd_soc_cml_rt1011_rt5682]
[   23.302389]  platform_drv_probe+0x66/0xc0

Fixes: 629ba12e ("ASoC: Intel: boards: split woofer and tweeter support")
Suggested-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: default avatarFred Oh <fred.oh@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20200625191308.3322-12-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent e1a31c09
......@@ -34,7 +34,6 @@
#define SOF_RT1011_SPEAKER_WR BIT(1)
#define SOF_RT1011_SPEAKER_TL BIT(2)
#define SOF_RT1011_SPEAKER_TR BIT(3)
#define SPK_CH 4
/* Default: Woofer speakers */
static unsigned long sof_rt1011_quirk = SOF_RT1011_SPEAKER_WL |
......@@ -383,10 +382,17 @@ SND_SOC_DAILINK_DEF(ssp0_codec,
SND_SOC_DAILINK_DEF(ssp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
SND_SOC_DAILINK_DEF(ssp1_codec,
SND_SOC_DAILINK_DEF(ssp1_codec_2spk,
DAILINK_COMP_ARRAY(
/* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
/* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI)));
SND_SOC_DAILINK_DEF(ssp1_codec_4spk,
DAILINK_COMP_ARRAY(
/* WL */ COMP_CODEC("i2c-10EC1011:00", CML_RT1011_CODEC_DAI),
/* WR */ COMP_CODEC("i2c-10EC1011:01", CML_RT1011_CODEC_DAI),
/* TL */ COMP_CODEC("i2c-10EC1011:02", CML_RT1011_CODEC_DAI),
/* TR */ COMP_CODEC("i2c-10EC1011:03", CML_RT1011_CODEC_DAI)));
SND_SOC_DAILINK_DEF(dmic_pin,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
......@@ -483,7 +489,7 @@ static struct snd_soc_dai_link cml_rt1011_rt5682_dailink[] = {
.no_pcm = 1,
.init = cml_rt1011_spk_init,
.ops = &cml_rt1011_ops,
SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec_2spk, platform),
},
};
......@@ -496,6 +502,15 @@ static struct snd_soc_codec_conf rt1011_conf[] = {
.dlc = COMP_CODEC_CONF("i2c-10EC1011:01"),
.name_prefix = "WR",
},
/* single configuration structure for 2 and 4 channels */
{
.dlc = COMP_CODEC_CONF("i2c-10EC1011:02"),
.name_prefix = "TL",
},
{
.dlc = COMP_CODEC_CONF("i2c-10EC1011:03"),
.name_prefix = "TR",
},
};
/* Cometlake audio machine driver for RT1011 and RT5682 */
......@@ -518,8 +533,6 @@ static struct snd_soc_card snd_soc_card_cml = {
static int snd_cml_rt1011_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link_component *rt1011_dais_components;
struct snd_soc_codec_conf *rt1011_dais_confs;
struct card_private *ctx;
struct snd_soc_acpi_mach *mach;
const char *platform_name;
......@@ -538,65 +551,15 @@ static int snd_cml_rt1011_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "sof_rt1011_quirk = %lx\n", sof_rt1011_quirk);
/* when 4 speaker is available, update codec config */
if (sof_rt1011_quirk & (SOF_RT1011_SPEAKER_TL |
SOF_RT1011_SPEAKER_TR)) {
rt1011_dais_confs = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_codec_conf) *
SPK_CH, GFP_KERNEL);
if (!rt1011_dais_confs)
return -ENOMEM;
rt1011_dais_components = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_dai_link_component) *
SPK_CH, GFP_KERNEL);
if (!rt1011_dais_components)
return -ENOMEM;
for (i = 0; i < SPK_CH; i++) {
rt1011_dais_confs[i].dlc.name = devm_kasprintf(&pdev->dev,
GFP_KERNEL,
"i2c-10EC1011:0%d",
i);
if (!rt1011_dais_confs[i].dlc.name)
return -ENOMEM;
switch (i) {
case 0:
rt1011_dais_confs[i].name_prefix = "WL";
break;
case 1:
rt1011_dais_confs[i].name_prefix = "WR";
break;
case 2:
rt1011_dais_confs[i].name_prefix = "TL";
break;
case 3:
rt1011_dais_confs[i].name_prefix = "TR";
break;
default:
return -EINVAL;
}
rt1011_dais_components[i].name = devm_kasprintf(&pdev->dev,
GFP_KERNEL,
"i2c-10EC1011:0%d",
i);
if (!rt1011_dais_components[i].name)
return -ENOMEM;
rt1011_dais_components[i].dai_name = CML_RT1011_CODEC_DAI;
}
snd_soc_card_cml.codec_conf = rt1011_dais_confs;
snd_soc_card_cml.num_configs = SPK_CH;
for (i = 0; i < ARRAY_SIZE(cml_rt1011_rt5682_dailink); i++) {
if (!strcmp(cml_rt1011_rt5682_dailink[i].codecs->dai_name,
CML_RT1011_CODEC_DAI)) {
cml_rt1011_rt5682_dailink[i].codecs = rt1011_dais_components;
cml_rt1011_rt5682_dailink[i].num_codecs = SPK_CH;
CML_RT1011_CODEC_DAI)) {
cml_rt1011_rt5682_dailink[i].codecs = ssp1_codec_4spk;
cml_rt1011_rt5682_dailink[i].num_codecs =
ARRAY_SIZE(ssp1_codec_4spk);
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment