Browse Source

Merge "asoc: Add check for substream ref_count before access the substream."

qctecmdr 4 years ago
parent
commit
dd8e5009d5
3 changed files with 80 additions and 35 deletions
  1. 22 12
      asoc/msm-pcm-loopback-v2.c
  2. 11 7
      asoc/msm-pcm-q6-noirq.c
  3. 47 16
      asoc/msm-pcm-q6-v2.c

+ 22 - 12
asoc/msm-pcm-loopback-v2.c

@@ -552,13 +552,15 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
 		goto exit;
 	}
 	mutex_lock(&loopback_session_lock);
-	prtd = substream->runtime->private_data;
-	if (!prtd) {
-		rc = -ENODEV;
-		mutex_unlock(&loopback_session_lock);
-		goto exit;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (!prtd) {
+			rc = -ENODEV;
+			mutex_unlock(&loopback_session_lock);
+			goto exit;
+		}
+		rc = pcm_loopback_set_volume(prtd, volume);
 	}
-	rc = pcm_loopback_set_volume(prtd, volume);
 	mutex_unlock(&loopback_session_lock);
 exit:
 	return rc;
@@ -584,13 +586,15 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol,
 		goto exit;
 	}
 	mutex_lock(&loopback_session_lock);
-	prtd = substream->runtime->private_data;
-	if (!prtd) {
-		rc = -ENODEV;
-		mutex_unlock(&loopback_session_lock);
-		goto exit;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (!prtd) {
+			rc = -ENODEV;
+			mutex_unlock(&loopback_session_lock);
+			goto exit;
+		}
+		ucontrol->value.integer.value[0] = prtd->volume;
 	}
-	ucontrol->value.integer.value[0] = prtd->volume;
 	mutex_unlock(&loopback_session_lock);
 exit:
 	return rc;
@@ -888,6 +892,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 			chmixer_pspd);
 
 	mutex_lock(&loopback_session_lock);
+	if (substream->ref_count <= 0) {
+		pr_err_ratelimited("%s: substream ref_count:%d invalid\n",
+				__func__, substream->ref_count);
+		mutex_unlock(&loopback_session_lock);
+		return -EINVAL;
+	}
 	if (chmixer_pspd->enable && substream->runtime) {
 		prtd = substream->runtime->private_data;
 		if (!prtd) {

+ 11 - 7
asoc/msm-pcm-q6-noirq.c

@@ -762,9 +762,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol,
 		return -ENODEV;
 	}
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd)
-		ucontrol->value.integer.value[0] = prtd->volume;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd)
+			ucontrol->value.integer.value[0] = prtd->volume;
+	}
 	mutex_unlock(&pdata->lock);
 	return 0;
 }
@@ -807,10 +809,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
 	}
 
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd) {
-		rc = msm_pcm_set_volume(prtd, volume);
-		prtd->volume = volume;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd) {
+			rc = msm_pcm_set_volume(prtd, volume);
+			prtd->volume = volume;
+		}
 	}
 	mutex_unlock(&pdata->lock);
 	return rc;

+ 47 - 16
asoc/msm-pcm-q6-v2.c

@@ -1330,7 +1330,12 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
 		ret = -EINVAL;
 		goto done;
 	}
-
+	if (substream->ref_count <= 0) {
+		pr_err_ratelimited("%s substream ref_count:%d invalid\n",
+				__func__, substream->ref_count);
+		ret = -EINVAL;
+		goto done;
+	}
 	prtd = substream->runtime->private_data;
 	if (prtd == NULL) {
 		pr_err("%s prtd is null.\n", __func__);
@@ -1561,9 +1566,11 @@ static int msm_pcm_volume_ctl_get(struct snd_kcontrol *kcontrol,
 	}
 
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd)
-		ucontrol->value.integer.value[0] = prtd->volume;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd)
+			ucontrol->value.integer.value[0] = prtd->volume;
+	}
 	mutex_unlock(&pdata->lock);
 	return 0;
 }
@@ -1607,10 +1614,12 @@ static int msm_pcm_volume_ctl_put(struct snd_kcontrol *kcontrol,
 	}
 
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd) {
-		rc = msm_pcm_set_volume(prtd, volume);
-		prtd->volume = volume;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd) {
+			rc = msm_pcm_set_volume(prtd, volume);
+			prtd->volume = volume;
+		}
 	}
 	mutex_unlock(&pdata->lock);
 	return rc;
@@ -1678,9 +1687,11 @@ static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
 		return 0;
 	}
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd)
-		ucontrol->value.integer.value[0] = prtd->compress_enable;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd)
+			ucontrol->value.integer.value[0] = prtd->compress_enable;
+	}
 	mutex_unlock(&pdata->lock);
 	return 0;
 }
@@ -1710,11 +1721,13 @@ static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
 		return 0;
 	}
 	mutex_lock(&pdata->lock);
-	prtd = substream->runtime->private_data;
-	if (prtd) {
-		pr_debug("%s: setting compress flag to 0x%x\n",
-		__func__, compress);
-		prtd->compress_enable = compress;
+	if (substream->ref_count > 0) {
+		prtd = substream->runtime->private_data;
+		if (prtd) {
+			pr_debug("%s: setting compress flag to 0x%x\n",
+			__func__, compress);
+			prtd->compress_enable = compress;
+		}
 	}
 	mutex_unlock(&pdata->lock);
 	return rc;
@@ -1824,6 +1837,12 @@ static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
 		return 0;
 
 	mutex_lock(&pdata->lock);
+	if (substream->ref_count <= 0) {
+		pr_err_ratelimited("%s: substream ref_count:%d invalid\n",
+				__func__, substream->ref_count);
+		mutex_unlock(&pdata->lock);
+		return -EINVAL;
+	}
 	prtd = substream->runtime ? substream->runtime->private_data : NULL;
 	if (prtd) {
 		prtd->set_channel_map = true;
@@ -1891,6 +1910,12 @@ static int msm_pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
 		return 0; /* no channels set */
 
 	mutex_lock(&pdata->lock);
+	if (substream->ref_count <= 0) {
+		pr_err_ratelimited("%s: substream ref_count:%d invalid\n",
+				__func__, substream->ref_count);
+		mutex_unlock(&pdata->lock);
+		return -EINVAL;
+	}
 	prtd = substream->runtime ? substream->runtime->private_data : NULL;
 
 	if (prtd && prtd->set_channel_map == true) {
@@ -2180,6 +2205,12 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 	}
 
 	mutex_lock(&pdata->lock);
+	if (substream->ref_count <= 0) {
+		pr_err_ratelimited("%s: substream ref_count:%d invalid\n",
+				__func__, substream->ref_count);
+		mutex_unlock(&pdata->lock);
+		return -EINVAL;
+	}
 	prtd = substream->runtime ? substream->runtime->private_data : NULL;
 	if (chmixer_pspd->enable && prtd) {
 		if (session_type == SESSION_TYPE_RX &&