Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3184270e authored by Libin Yang's avatar Libin Yang Committed by Takashi Iwai
Browse files

ALSA: hda - hdmi get jack from hda_jack_tbl when not dyn_pcm_assign



On Intel platform, if !dyn_pcm_assign, spec->pcm_rec[].jack is not
NULL even after snd_hda_jack_tbl_clear() is called to free snd_jack.
This may cause access invalid memory when calling snd_jack_report.

Fixes: 25e4abb3 ('ALSA: hda - hdmi jack created based on pcm')
Signed-off-by: default avatarLibin Yang <libin.yang@linux.intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ea790053
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -1956,6 +1956,29 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
	return ret;
}

static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec,
				 struct hdmi_spec_per_pin *per_pin)
{
	struct hdmi_spec *spec = codec->spec;
	struct snd_jack *jack = NULL;
	struct hda_jack_tbl *jack_tbl;

	/* if !dyn_pcm_assign, get jack from hda_jack_tbl
	 * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
	 * NULL even after snd_hda_jack_tbl_clear() is called to
	 * free snd_jack. This may cause access invalid memory
	 * when calling snd_jack_report
	 */
	if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign)
		jack = spec->pcm_rec[per_pin->pcm_idx].jack;
	else if (!spec->dyn_pcm_assign) {
		jack_tbl = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);
		if (jack_tbl)
			jack = jack_tbl->jack;
	}
	return jack;
}

/* update ELD and jack state via audio component */
static void sync_eld_via_acomp(struct hda_codec *codec,
			       struct hdmi_spec_per_pin *per_pin)
@@ -1989,11 +2012,10 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
	/* pcm_idx >=0 before update_eld() means it is in monitor
	 * disconnected event. Jack must be fetched before update_eld()
	 */
	if (per_pin->pcm_idx >= 0)
		jack = spec->pcm_rec[per_pin->pcm_idx].jack;
	jack = pin_idx_to_jack(codec, per_pin);
	update_eld(codec, per_pin, eld);
	if (jack == NULL && per_pin->pcm_idx >= 0)
		jack = spec->pcm_rec[per_pin->pcm_idx].jack;
	if (jack == NULL)
		jack = pin_idx_to_jack(codec, per_pin);
	if (jack == NULL)
		goto unlock;
	snd_jack_report(jack,