Browse Source

ASoC: msm: check payload size before memory allocation

Buffer from mixer ctl or ADSP is composed of payload size and
actual payload. On a 32 bit platform, we could have an overflow
if payload size is below UINT_MAX while payload size + sizeof(struct)
is over UINT_MAX. Allocated memory size would be less than expected.
Check payload size against limit before memory allocation.

Change-Id: I0bf19ca7b8c93083177a21ad726122dc20f45551
Signed-off-by: Xiaojun Sang <[email protected]>
Xiaojun Sang 7 years ago
parent
commit
75642c362c

+ 2 - 2
asoc/msm-compress-q6-v2.c

@@ -3681,8 +3681,8 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
 		goto done;
 	}
 
-	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
-					sizeof(ucontrol->value.bytes.data)) {
+	if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
+			- sizeof(struct msm_adsp_event_data)) {
 		pr_err("%s param length=%d  exceeds limit",
 			__func__, event_data->payload_len);
 		ret = -EINVAL;

+ 2 - 2
asoc/msm-pcm-q6-v2.c

@@ -1138,8 +1138,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
 		goto done;
 	}
 
-	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
-					sizeof(ucontrol->value.bytes.data)) {
+	if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
+			- sizeof(struct msm_adsp_event_data)) {
 		pr_err("%s param length=%d  exceeds limit",
 			__func__, event_data->payload_len);
 		ret = -EINVAL;

+ 3 - 2
asoc/msm-qti-pp-config.c

@@ -1025,8 +1025,9 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd,
 
 	event_data = (struct msm_adsp_event_data *)payload;
 	kctl->info(kctl, &kctl_info);
-	if (sizeof(struct msm_adsp_event_data)
-		+ event_data->payload_len > kctl_info.count) {
+
+	if (event_data->payload_len >
+		kctl_info.count - sizeof(struct msm_adsp_event_data)) {
 		pr_err("%s: payload length exceeds limit of %u bytes.\n",
 			__func__, kctl_info.count);
 		ret = -EINVAL;

+ 3 - 3
asoc/msm-transcode-loopback-q6-v2.c

@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -539,8 +539,8 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
 		goto done;
 	}
 
-	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
-					sizeof(ucontrol->value.bytes.data)) {
+	if (event_data->payload_len > sizeof(ucontrol->value.bytes.data)
+			- sizeof(struct msm_adsp_event_data)) {
 		pr_err("%s param length=%d  exceeds limit",
 			 __func__, event_data->payload_len);
 		ret = -EINVAL;

+ 7 - 0
dsp/q6asm.c

@@ -2230,6 +2230,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
 		 * package is composed of event type + size + actual payload
 		 */
 		payload_size = data->payload_size;
+		if (payload_size > UINT_MAX - sizeof(struct msm_adsp_event_data)) {
+			pr_err("%s: payload size = %d exceeds limit.\n",
+				__func__, payload_size);
+			spin_unlock(&(session[session_id].session_lock));
+			return -EINVAL;
+		}
+
 		pp_event_package = kzalloc(payload_size
 				+ sizeof(struct msm_adsp_event_data),
 				GFP_ATOMIC);