diff options
author | Wu Fengguang <fengguang.wu@intel.com> | 2011-11-16 03:29:46 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-11-16 04:44:21 -0500 |
commit | b95d68b8179764e29558b75cec35ef4a6a98925b (patch) | |
tree | 875fb72efe3cefea4df2bb37404dd32590666065 /sound | |
parent | e53de8f00c80fd1a312c95bc5157fdb98d46e070 (diff) |
ALSA: hda - fix ELD memory leak
memset(eld) clears eld->proc_entry which will leak the struct
snd_info_entry when unloading module.
Fix it by
- memset only the fields before eld->eld_buffer
- set eld->eld_valid to true _after_ all eld fields have been filled
Cc: <stable@kernel.org>
Cc: Pierre-louis Bossart <pierre-louis.bossart@intel.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_eld.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 11 |
3 files changed, 9 insertions, 10 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 1c8ddf547a2d..a065d6d2d6ff 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -297,10 +297,10 @@ static int hdmi_update_eld(struct hdmi_eld *e, | |||
297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); | 297 | buf + ELD_FIXED_BYTES + mnl + 3 * i); |
298 | } | 298 | } |
299 | 299 | ||
300 | e->eld_valid = true; | ||
300 | return 0; | 301 | return 0; |
301 | 302 | ||
302 | out_fail: | 303 | out_fail: |
303 | e->eld_ver = 0; | ||
304 | return -EINVAL; | 304 | return -EINVAL; |
305 | } | 305 | } |
306 | 306 | ||
@@ -323,9 +323,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
323 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() | 323 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() |
324 | */ | 324 | */ |
325 | 325 | ||
326 | if (!eld->eld_valid) | ||
327 | return -ENOENT; | ||
328 | |||
329 | size = snd_hdmi_get_eld_size(codec, nid); | 326 | size = snd_hdmi_get_eld_size(codec, nid); |
330 | if (size == 0) { | 327 | if (size == 0) { |
331 | /* wfg: workaround for ASUS P5E-VM HDMI board */ | 328 | /* wfg: workaround for ASUS P5E-VM HDMI board */ |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 6579e0f2bb57..618ddad17236 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -653,6 +653,9 @@ struct hdmi_eld { | |||
653 | int spk_alloc; | 653 | int spk_alloc; |
654 | int sad_count; | 654 | int sad_count; |
655 | struct cea_sad sad[ELD_MAX_SAD]; | 655 | struct cea_sad sad[ELD_MAX_SAD]; |
656 | /* | ||
657 | * all fields above eld_buffer will be cleared before updating ELD | ||
658 | */ | ||
656 | char eld_buffer[ELD_MAX_SIZE]; | 659 | char eld_buffer[ELD_MAX_SIZE]; |
657 | #ifdef CONFIG_PROC_FS | 660 | #ifdef CONFIG_PROC_FS |
658 | struct snd_info_entry *proc_entry; | 661 | struct snd_info_entry *proc_entry; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 81b7b791b3c3..aebfee50bd88 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -980,20 +980,19 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
980 | * the unsolicited response to avoid custom WARs. | 980 | * the unsolicited response to avoid custom WARs. |
981 | */ | 981 | */ |
982 | int present = snd_hda_pin_sense(codec, pin_nid); | 982 | int present = snd_hda_pin_sense(codec, pin_nid); |
983 | bool eld_valid = false; | ||
983 | 984 | ||
984 | memset(eld, 0, sizeof(*eld)); | 985 | memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); |
985 | 986 | ||
986 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 987 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
987 | if (eld->monitor_present) | 988 | if (eld->monitor_present) |
988 | eld->eld_valid = !!(present & AC_PINSENSE_ELDV); | 989 | eld_valid = !!(present & AC_PINSENSE_ELDV); |
989 | else | ||
990 | eld->eld_valid = 0; | ||
991 | 990 | ||
992 | printk(KERN_INFO | 991 | printk(KERN_INFO |
993 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", | 992 | "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", |
994 | codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); | 993 | codec->addr, pin_nid, eld->monitor_present, eld_valid); |
995 | 994 | ||
996 | if (eld->eld_valid) | 995 | if (eld_valid) |
997 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 996 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
998 | snd_hdmi_show_eld(eld); | 997 | snd_hdmi_show_eld(eld); |
999 | 998 | ||