ALSA: hda - hdmi get jack from hda_jack_tbl when not dyn_pcm_assign
PATCH 1/1 ALSA: hda - hdmi get jack from hda_jack_tbl when not dyn_pcm_assign
From: Libin Yang <[email protected]>
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.
Signed-off-by Libin Yang <[email protected]>
--- sound/pci/hda/patch_hdmi.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
sound/pci/hda/patch_hdmi.c +26 -4
@@ -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,
Signature · 1 line
1.9.1
Takashi Iwai
AppliedQuoted 8 lines · On Fri, 19 Feb 2016 08:42:06 +0100, [email protected] wrote:
From: Libin Yang <[email protected]>
On Intel platform, if !dyn_pcm_assign, spec->pcm_rec[].jack is not NULL even after
snd_hda_jack_tbl_clear()is called to freesnd_jack. This may cause access invalid memory when callingsnd_jack_report.Signed-off-by Libin Yang <[email protected]>
Applied, thanks.
Takashi
Quoted 56 lines
--- sound/pci/hda/patch_hdmi.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)sound/pci/hda/patch_hdmi.c +26
-4@@ -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,Signature · 1 line
1.9.1