Prechádzať zdrojové kódy

dsp: asm: Add check for num_channels before calling q6asm_map_channels

Channel_mapping array size varies for different commands.
Add check for num_channels before calling q6asm_map_channels.

Change-Id: Iccbcfe82f716fc0ffe0a26b1779dcaa1c3cb805b
Signed-off-by: Rohit kumar <[email protected]>
Rohit kumar 6 rokov pred
rodič
commit
2a64e52662
4 zmenil súbory, kde vykonal 120 pridanie a 1 odobranie
  1. 10 0
      asoc/msm-compress-q6-v2.c
  2. 10 0
      asoc/msm-pcm-loopback-v2.c
  3. 10 0
      asoc/msm-pcm-q6-v2.c
  4. 90 1
      dsp/q6asm.c

+ 10 - 0
asoc/msm-compress-q6-v2.c

@@ -4712,6 +4712,11 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 					chmixer_pspd->in_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
+				if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+					pr_err("%s: Invalid channel count %d\n",
+						__func__, chmixer_pspd->input_channel);
+					return -EINVAL;
+				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->input_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -4726,6 +4731,11 @@ static int msm_compr_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 					chmixer_pspd->out_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
+				if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+					pr_err("%s: Invalid channel count %d\n",
+						__func__, chmixer_pspd->output_channel);
+					return -EINVAL;
+				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->output_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)

+ 10 - 0
asoc/msm-pcm-loopback-v2.c

@@ -809,6 +809,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 	if (chmixer_pspd->enable) {
 		if (session_type == SESSION_TYPE_RX &&
 			!chmixer_pspd->override_in_ch_map) {
+			if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+				pr_err("%s: Invalid channel count %d\n",
+					__func__, chmixer_pspd->input_channel);
+				return -EINVAL;
+			}
 			q6asm_map_channels(asm_ch_map,
 				chmixer_pspd->input_channel, false);
 			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -817,6 +822,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 			reset_override_in_ch_map = true;
 		} else if (session_type == SESSION_TYPE_TX &&
 			!chmixer_pspd->override_out_ch_map) {
+			if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+				pr_err("%s: Invalid channel count %d\n",
+					__func__, chmixer_pspd->output_channel);
+				return -EINVAL;
+			}
 			q6asm_map_channels(asm_ch_map,
 				chmixer_pspd->output_channel, false);
 			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)

+ 10 - 0
asoc/msm-pcm-q6-v2.c

@@ -1939,6 +1939,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 					chmixer_pspd->in_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
+				if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+					pr_err("%s: Invalid channel count %d\n",
+						__func__, chmixer_pspd->input_channel);
+					return -EINVAL;
+				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->input_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -1954,6 +1959,11 @@ static int msm_pcm_channel_mixer_cfg_ctl_put(struct snd_kcontrol *kcontrol,
 					chmixer_pspd->out_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
+				if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+					pr_err("%s: Invalid channel count %d\n",
+						__func__, chmixer_pspd->output_channel);
+					return -EINVAL;
+				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->output_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)

+ 90 - 1
dsp/q6asm.c

@@ -4265,6 +4265,12 @@ int q6asm_open_shared_io(struct audio_client *ac,
 		return -EINVAL;
 	}
 
+	if (config->channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__,
+			config->channels);
+		return -EINVAL;
+	}
+
 	bufsz = config->bufsz;
 	bufcnt = config->bufcnt;
 	num_watermarks = 0;
@@ -4664,6 +4670,11 @@ int q6asm_enc_cfg_blk_custom(struct audio_client *ac,
 
 	custom_size = enc_generic->reserved[1];
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d] size[%d] res[2]=[%d] res[3]=[%d]\n",
 		 __func__, ac->session, custom_size, enc_generic->reserved[2],
 		 enc_generic->reserved[3]);
@@ -4882,6 +4893,12 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc = 0;
 
+	if (num_channels > MAX_CHAN_MAP_CHANNELS) {
+		pr_err("%s: Invalid channel count %d\n", __func__,
+			num_channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: Session %d, num_channels = %d\n",
 			 __func__, ac->session, num_channels);
 	q6asm_add_hdr(ac, &chan_map.hdr, sizeof(chan_map), TRUE);
@@ -4964,6 +4981,12 @@ static int q6asm_enc_cfg_blk_pcm_v5(struct audio_client *ac,
 		goto fail_cmd;
 	}
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -5066,6 +5089,12 @@ int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
 		goto fail_cmd;
 	}
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -5166,6 +5195,12 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
 		goto fail_cmd;
 	}
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -5263,6 +5298,11 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
 		return -EINVAL;
 	}
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
 			 ac->session, rate, channels);
 
@@ -5478,9 +5518,13 @@ int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac,
 	struct asm_multi_channel_pcm_enc_cfg_v2  enc_cfg;
 	u8 *channel_mapping;
 	u32 frames_per_buf = 0;
-
 	int rc = 0;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
 			 ac->session, rate, channels);
 
@@ -6098,6 +6142,11 @@ static int __q6asm_media_format_block_pcm(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc = 0;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
 		channels);
 
@@ -6181,6 +6230,11 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -6265,6 +6319,11 @@ static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -6352,6 +6411,11 @@ static int __q6asm_media_format_block_pcm_v5(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -6604,6 +6668,11 @@ static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc = 0;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
 		channels);
 
@@ -6672,6 +6741,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -6744,6 +6818,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -6818,6 +6897,11 @@ static int __q6asm_media_format_block_multi_ch_pcm_v5(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
 		 ac->session, rate, channels,
 		 bits_per_sample, sample_word_size);
@@ -7010,6 +7094,11 @@ int q6asm_media_format_block_gen_compr(struct audio_client *ac,
 	u8 *channel_mapping;
 	int rc = 0;
 
+	if (channels > PCM_FORMAT_MAX_NUM_CHANNEL) {
+		pr_err("%s: Invalid channel count %d\n", __func__, channels);
+		return -EINVAL;
+	}
+
 	pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n",
 		 __func__, ac->session, rate,
 		 channels, bits_per_sample);