Skip to content

Commit f32c80d

Browse files
soyersoyerbroonie
authored andcommitted
ASoC: tas2781: check the validity of prm_no/cfg_no
Add additional checks for program/config numbers to avoid loading from invalid addresses. If prm_no/cfg_no is negative, skip uploading program/config. The tas2781-hda driver caused a NULL pointer dereference after loading module, and before first runtime_suspend. the state was: tas_priv->cur_conf = -1; tas_priv->tasdevice[i].cur_conf = 0; program = &(tas_fmw->programs[-1]); BUG: kernel NULL pointer dereference, address: 0000000000000010 Call Trace: <TASK> ? __die+0x23/0x70 ? page_fault_oops+0x171/0x4e0 ? vprintk_emit+0x175/0x2b0 ? exc_page_fault+0x7f/0x180 ? asm_exc_page_fault+0x26/0x30 ? tasdevice_load_block_kernel+0x21/0x310 [snd_soc_tas2781_fmwlib] tasdevice_select_tuningprm_cfg+0x268/0x3a0 [snd_soc_tas2781_fmwlib] tasdevice_tuning_switch+0x69/0x710 [snd_soc_tas2781_fmwlib] tas2781_hda_playback_hook+0xd4/0x110 [snd_hda_scodec_tas2781_i2c] Fixes: 915f5ea ("ASoC: tas2781: firmware lib") CC: <[email protected]> Signed-off-by: Gergo Koteles <[email protected]> Link: https://msgid.link/r/523780155bfdca9bc0acd39efc79ed039454818d.1702591356.git.soyer@irl.hu Signed-off-by: Mark Brown <[email protected]>
1 parent dc96528 commit f32c80d

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

sound/soc/codecs/tas2781-fmwlib.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,11 +2189,11 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
21892189
goto out;
21902190
}
21912191

2192-
conf = &(tas_fmw->configs[cfg_no]);
21932192
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
21942193
if (cfg_info[rca_conf_no]->active_dev & (1 << i)) {
2195-
if (tas_priv->tasdevice[i].cur_prog != prm_no
2196-
|| tas_priv->force_fwload_status) {
2194+
if (prm_no >= 0
2195+
&& (tas_priv->tasdevice[i].cur_prog != prm_no
2196+
|| tas_priv->force_fwload_status)) {
21972197
tas_priv->tasdevice[i].cur_conf = -1;
21982198
tas_priv->tasdevice[i].is_loading = true;
21992199
prog_status++;
@@ -2228,7 +2228,8 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
22282228
}
22292229

22302230
for (i = 0, status = 0; i < tas_priv->ndev; i++) {
2231-
if (tas_priv->tasdevice[i].cur_conf != cfg_no
2231+
if (cfg_no >= 0
2232+
&& tas_priv->tasdevice[i].cur_conf != cfg_no
22322233
&& (cfg_info[rca_conf_no]->active_dev & (1 << i))
22332234
&& (tas_priv->tasdevice[i].is_loaderr == false)) {
22342235
status++;
@@ -2238,6 +2239,7 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
22382239
}
22392240

22402241
if (status) {
2242+
conf = &(tas_fmw->configs[cfg_no]);
22412243
status = 0;
22422244
tasdevice_load_data(tas_priv, &(conf->dev_data));
22432245
for (i = 0; i < tas_priv->ndev; i++) {
@@ -2281,7 +2283,7 @@ int tasdevice_prmg_load(void *context, int prm_no)
22812283
}
22822284

22832285
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2284-
if (tas_priv->tasdevice[i].cur_prog != prm_no) {
2286+
if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
22852287
tas_priv->tasdevice[i].cur_conf = -1;
22862288
tas_priv->tasdevice[i].is_loading = true;
22872289
prog_status++;
@@ -2326,7 +2328,7 @@ int tasdevice_prmg_calibdata_load(void *context, int prm_no)
23262328
}
23272329

23282330
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2329-
if (tas_priv->tasdevice[i].cur_prog != prm_no) {
2331+
if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
23302332
tas_priv->tasdevice[i].cur_conf = -1;
23312333
tas_priv->tasdevice[i].is_loading = true;
23322334
prog_status++;

0 commit comments

Comments
 (0)