[alsa-devel] [PATCH 11/11] ASoC: hdac_hdmi: Fix possible memory leak on parse and map nid failure

Guneshwor Singh guneshwor.o.singh at intel.com
Tue Nov 7 11:46:26 CET 2017


From: "Subhransu S. Prusty" <subhransu.s.prusty at intel.com>

During failure, widgets in cvt_list and pin_list are not freed. So fix
the possible memory leak by freeing them when failure occurs.

Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty at intel.com>
Signed-off-by: Guneshwor Singh <guneshwor.o.singh at intel.com>
---
 sound/soc/codecs/hdac_hdmi.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 0c0aa6182502..f3b4f4dfae6a 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1453,6 +1453,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
 	int i, num_nodes;
 	struct hdac_device *hdac = &edev->hdac;
 	struct hdac_hdmi_priv *hdmi = edev->private_data;
+	struct hdac_hdmi_cvt *temp_cvt, *cvt_next;
+	struct hdac_hdmi_pin *temp_pin, *pin_next;
 	int ret;
 
 	hdac_hdmi_skl_enable_all_pins(hdac);
@@ -1482,32 +1484,54 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
 		case AC_WID_AUD_OUT:
 			ret = hdac_hdmi_add_cvt(edev, nid);
 			if (ret < 0)
-				return ret;
+				goto free_widgets;
 			break;
 
 		case AC_WID_PIN:
 			ret = hdac_hdmi_add_pin(edev, nid);
 			if (ret < 0)
-				return ret;
+				goto free_widgets;
 			break;
 		}
 	}
 
 	hdac->end_nid = nid;
 
-	if (!hdmi->num_pin || !hdmi->num_cvt)
-		return -EIO;
+	if (!hdmi->num_pin || !hdmi->num_cvt) {
+		ret = -EIO;
+		goto free_widgets;
+	}
 
 	ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
 	if (ret) {
 		dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
 							ret);
-		return ret;
+		goto free_widgets;
 	}
 
 	*num_dais = hdmi->num_cvt;
+	ret = hdac_hdmi_init_dai_map(edev);
+	if (ret < 0)
+		goto free_widgets;
 
-	return hdac_hdmi_init_dai_map(edev);
+	return ret;
+
+free_widgets:
+	list_for_each_entry_safe(temp_cvt, cvt_next, &hdmi->cvt_list, head) {
+		list_del(&temp_cvt->head);
+		kfree(temp_cvt->name);
+		kfree(temp_cvt);
+	}
+
+	list_for_each_entry_safe(temp_pin, pin_next, &hdmi->pin_list, head) {
+		for (i = 0; i < temp_pin->num_ports; i++)
+			temp_pin->ports[i].pin = NULL;
+		kfree(temp_pin->ports);
+		list_del(&temp_pin->head);
+		kfree(temp_pin);
+	}
+
+	return ret;
 }
 
 static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
-- 
2.14.2



More information about the Alsa-devel mailing list