From dcfb376d706d85a27a9cdbda43b4701747dafd6f Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 5 Apr 2023 15:46:55 +0530 Subject: [PATCH 1/6] dsp: q6adm: Resolve mem corruption in adm cb Conversion of negative "num_modules" var value will result in max possible unsigned int value and hence can cause mem corruption when accessed. Resolve this by assigning the same data type to "num_modules" var as used in the calling fn. Change-Id: I4c9d7215b9c7345637e1eb3a1992a41fef71c5cb Signed-off-by: Soumya Managoli --- dsp/q6adm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dsp/q6adm.c b/dsp/q6adm.c index f2ae327ee554..712ba088baeb 100644 --- a/dsp/q6adm.c +++ b/dsp/q6adm.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -1668,7 +1668,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) { uint32_t *payload; int port_idx, copp_idx, idx, client_id; - int num_modules; + uint32_t num_modules; int ret; int payload_size = 0, i = 0; struct msm_adsp_event_data *pp_event_package = NULL; From 3ebb66aa5dfe4f4c71d359a0035a1c600f43fc5a Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Thu, 6 Apr 2023 13:55:23 +0530 Subject: [PATCH 2/6] ASoC: msm-pcm-host-voice: Handle OOB access in hpcm_start There is no error check for case when hpcm_start is called for the same RX or TX tap points multiple times. This can result in OOB access of struct vss_ivpcm_tap_point. Handle this scenario with appropriate no_of_tp check. Change-Id: Ib384d21c9bf372f3e5d78f64b5c056e836728399 Signed-off-by: Soumya Managoli --- asoc/msm-pcm-host-voice-v2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 4496e05a966a..50fbd15d0481 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -626,6 +627,12 @@ static int hpcm_start_vocpcm(char *pcm_id, struct hpcm_drv *prtd, } } + if (*no_of_tp != no_of_tp_req && *no_of_tp > 2) { + pr_err("%s:: Invalid hpcm start request\n", __func__); + memset(&prtd->start_cmd, 0, sizeof(struct start_cmd)); + return -EINVAL; + } + if ((prtd->mixer_conf.tx.enable || prtd->mixer_conf.rx.enable) && *no_of_tp == no_of_tp_req) { voc_send_cvp_start_vocpcm(voc_get_session_id(sess_name), From 8c0d7cffabc96ab0bfe87df61f5b35b92cf9533e Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Tue, 11 Apr 2023 10:17:55 +0530 Subject: [PATCH 3/6] dsp: q6voice: Add buf size check for cvs cal data Check for the max size of cvs command register calibration data that can be copied else will result in buffer overflow. Change-Id: Id7a4c5a9795143798b68dfde779f17fb450e3848 Signed-off-by: Soumya Managoli --- dsp/q6voice.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dsp/q6voice.c b/dsp/q6voice.c index 1f3b1448fb8d..0f2fe8ccc1b4 100644 --- a/dsp/q6voice.c +++ b/dsp/q6voice.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -2852,6 +2852,13 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v) goto unlock; } + if (col_data->cal_data.size >= MAX_COL_INFO_SIZE) { + pr_err("%s: Invalid cal data size %d!\n", + __func__, col_data->cal_data.size); + ret = -EINVAL; + goto unlock; + } + memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0], (void *) &((struct audio_cal_info_voc_col *) col_data->cal_info)->data, From 3b0442cec3d57c0b8a8d44c4832f837013c23b2f Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 12 Apr 2023 12:34:26 +0530 Subject: [PATCH 4/6] dsp: q6core: Avoid OOB access in q6core "num_services", a signed integer when compared with constant results in conversion of signed integer to max possible unsigned int value when "num_services" is a negative value. This can lead to OOB read. Fix is to handle this case. Change-Id: Id6a8f150d9019c972a87f789e4c626337a97bfff Signed-off-by: Soumya Managoli --- dsp/q6core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index 2fce87998485..35fc8a801261 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -204,7 +205,7 @@ EXPORT_SYMBOL(q6core_send_uevent); static int parse_fwk_version_info(uint32_t *payload, uint16_t payload_size) { size_t ver_size; - int num_services; + uint16_t num_services; pr_debug("%s: Payload info num services %d\n", __func__, payload[4]); From 7756692d5419f47792b778f9cc4a43d468d0bee8 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Wed, 12 Apr 2023 14:27:28 +0530 Subject: [PATCH 5/6] ASoC: msm-pcm-host-voice: Address buffer overflow in hpcm capture copy There is no check for the copy data size of the ADSP returned payload. Add check for the max hpcm_buf_node size before copy to avoid buffer out of bounds issue. Change-Id: Id647888430ce302359a857ef54d321bee99889bf Signed-off-by: Soumya Managoli --- asoc/msm-pcm-host-voice-v2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c index 4496e05a966a..b3100414af3a 100644 --- a/asoc/msm-pcm-host-voice-v2.c +++ b/asoc/msm-pcm-host-voice-v2.c @@ -683,6 +683,12 @@ static void hpcm_copy_capture_data_to_queue(struct dai_data *dai_data, if (dai_data->substream == NULL) return; + if (len >= HPCM_MAX_VOC_PKT_SIZE) { + pr_err("%s: Copy capture data len %d is > HPCM_MAX_VOC_PKT_SIZE\n", + __func__, len); + return; + } + /* Copy out buffer packet into free_queue */ spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags); From 2f6eb70111c444d23639c0bf3b625bf6140b1443 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 17 Apr 2023 17:02:59 +0530 Subject: [PATCH 6/6] ASoC: msm-pcm-voip: Avoid interger underflow There is no check for voip pkt pkt_len,if it contains the min required data. This can lead to integer underflow. Add check for the same. Change-Id: I4f57eb125967d52ad8da60d21a440af1f81d2579 Signed-off-by: Soumya Managoli --- asoc/msm-pcm-voip-v2.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c index 14803f1d235a..c926fa4e3037 100644 --- a/asoc/msm-pcm-voip-v2.c +++ b/asoc/msm-pcm-voip-v2.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -365,6 +366,13 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, switch (prtd->mode) { case MODE_AMR_WB: case MODE_AMR: { + if (pkt_len <= DSP_FRAME_HDR_LEN) { + pr_err("%s: pkt_len %d is < required len\n", + pkt_len); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, + dsp_flags); + return; + } /* Remove the DSP frame info header. Header format: * Bits 0-3: Frame rate * Bits 4-7: Frame type @@ -385,6 +393,13 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, case MODE_4GV_NB: case MODE_4GV_WB: case MODE_4GV_NW: { + if (pkt_len <= DSP_FRAME_HDR_LEN) { + pr_err("%s: pkt_len %d is < required len\n", + pkt_len); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, + dsp_flags); + return; + } /* Remove the DSP frame info header. * Header format: * Bits 0-3: frame rate @@ -422,6 +437,13 @@ static void voip_process_ul_pkt(uint8_t *voc_pkt, buf_node->frame.frm_hdr.timestamp = timestamp; voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN; + if (pkt_len <= 2 * DSP_FRAME_HDR_LEN) { + pr_err("%s: pkt_len %d is < required len\n", + pkt_len); + spin_unlock_irqrestore(&prtd->dsp_ul_lock, + dsp_flags); + return; + } /* There are two frames in the buffer. Length of the * first frame: */