]> git.hungrycats.org Git - linux/commitdiff
ALSA: hda - fix ELD memory leak
authorWu Fengguang <fengguang.wu@intel.com>
Tue, 22 Nov 2011 08:58:35 +0000 (16:58 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 26 Nov 2011 17:08:36 +0000 (09:08 -0800)
Backported from commit b95d68b8179764e29558b75cec35ef4a6a98925b.

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: 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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
sound/pci/hda/hda_eld.c
sound/pci/hda/patch_hdmi.c

index c34f730f481568042b334e4973ae0569f5fdea9b..44f199c69c4d45fd6281ee96f14b23e35616a732 100644 (file)
@@ -297,10 +297,10 @@ static int hdmi_update_eld(struct hdmi_eld *e,
                                        buf + ELD_FIXED_BYTES + mnl + 3 * i);
        }
 
+       e->eld_valid = true;
        return 0;
 
 out_fail:
-       e->eld_ver = 0;
        return -EINVAL;
 }
 
@@ -318,9 +318,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
        int size;
        unsigned char *buf;
 
-       if (!eld->eld_valid)
-               return -ENOENT;
-
        size = snd_hdmi_get_eld_size(codec, nid);
        if (size == 0) {
                /* wfg: workaround for ASUS P5E-VM HDMI board */
index 19cb72db9c38df1261f3ded1fe1c0471bd906aef..e287015cbbb3bc036fdb106c3a3aa3b9af144e13 100644 (file)
@@ -920,20 +920,23 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
         * the unsolicited response to avoid custom WARs.
         */
        int present = snd_hda_pin_sense(codec, pin_nid);
+       bool eld_valid = false;
 
-       memset(eld, 0, sizeof(*eld));
+#ifdef CONFIG_PROC_FS
+       memset(eld, 0, offsetof(struct hdmi_eld, proc_entry));
+#else
+       memset(eld, 0, sizeof(struct hdmi_eld));
+#endif
 
        eld->monitor_present    = !!(present & AC_PINSENSE_PRESENCE);
        if (eld->monitor_present)
-               eld->eld_valid  = !!(present & AC_PINSENSE_ELDV);
-       else
-               eld->eld_valid  = 0;
+               eld_valid       = !!(present & AC_PINSENSE_ELDV);
 
        printk(KERN_INFO
                "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
-               codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
+               codec->addr, pin_nid, eld->monitor_present, eld_valid);
 
-       if (eld->eld_valid)
+       if (eld_valid)
                if (!snd_hdmi_get_eld(eld, codec, pin_nid))
                        snd_hdmi_show_eld(eld);