Merge tag 'LA.UM.9.14.r1-22000-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/audio-kernel into android13-5.4-lahaina

"LA.UM.9.14.r1-22000-LAHAINA.QSSI12.0"

* tag 'LA.UM.9.14.r1-22000-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/audio-kernel:
  ASoC: msm-pcm-voip: Avoid interger underflow
  dsp: q6core: validate payload size before access for AVCS
  dsp:  afe: check for param size before copying
  ASoC: msm-pcm-voip: Avoid interger underflow
  ASoC: msm-pcm-host-voice: Address buffer overflow in hpcm capture copy
  dsp: q6core: Avoid OOB access in q6core
  dsp: q6voice: Add buf size check for cvs cal data
  ASoC: msm-pcm-host-voice: Handle OOB access in hpcm_start
  dsp: q6adm: Resolve mem corruption in adm cb

Change-Id: I049254180a236de36f3f526faa2e401c4dd805ee
This commit is contained in:
Michael Bestas 2023-07-11 15:49:56 +03:00
commit 7a406906ce
No known key found for this signature in database
GPG key ID: CC95044519BE6669
6 changed files with 142 additions and 5 deletions

View file

@ -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 <linux/init.h>
@ -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),
@ -683,6 +690,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);

View file

@ -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 <linux/init.h>
@ -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",
__func__, 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",
__func__, 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",
__func__, pkt_len);
spin_unlock_irqrestore(&prtd->dsp_ul_lock,
dsp_flags);
return;
}
/* There are two frames in the buffer. Length of the
* first frame:
*/
@ -457,6 +479,14 @@ 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",
__func__, pkt_len);
spin_unlock_irqrestore(&prtd->dsp_ul_lock,
dsp_flags);
return;
}
/* There are two frames in the buffer. Length
* of the second frame:
*/

View file

@ -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 <linux/module.h>
#include <linux/slab.h>
@ -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;

View file

@ -1,6 +1,6 @@
// 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 <linux/slab.h>
#include <linux/debugfs.h>
@ -786,32 +786,74 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
switch (param_hdr.param_id) {
case AFE_PARAM_ID_CALIB_RES_CFG_V2:
expected_size += sizeof(struct asm_calib_res_cfg);
if (param_hdr.param_size != sizeof(struct asm_calib_res_cfg)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.calib_data;
break;
case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS:
expected_size += sizeof(struct afe_sp_th_vi_ftm_params);
if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_ftm_params)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.th_vi_resp;
break;
case AFE_PARAM_ID_SP_V2_TH_VI_V_VALI_PARAMS:
expected_size += sizeof(struct afe_sp_th_vi_v_vali_params);
if (param_hdr.param_size != sizeof(struct afe_sp_th_vi_v_vali_params)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.th_vi_v_vali_resp;
break;
case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS:
expected_size += sizeof(struct afe_sp_ex_vi_ftm_params);
if (param_hdr.param_size != sizeof(struct afe_sp_ex_vi_ftm_params)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.ex_vi_resp;
break;
case AFE_PARAM_ID_SP_RX_TMAX_XMAX_LOGGING:
expected_size += sizeof(
struct afe_sp_rx_tmax_xmax_logging_param);
if (param_hdr.param_size != sizeof(struct afe_sp_rx_tmax_xmax_logging_param)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.xt_logging_resp;
break;
case AFE_PARAM_ID_SP_V4_CALIB_RES_CFG:
expected_size += sizeof(
struct afe_sp_v4_param_th_vi_calib_res_cfg);
if (param_hdr.param_size != sizeof(
struct afe_sp_v4_param_th_vi_calib_res_cfg)) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
data_dest = (u32 *) &this_afe.spv4_calib_data;
break;
case AFE_PARAM_ID_SP_V4_TH_VI_FTM_PARAMS:
num_ch = data_start[0];
if (num_ch > SP_V2_NUM_MAX_SPKRS) {
pr_err("%s: Error: num_ch %d is greater than expected\n",
__func__,num_ch);
return -EINVAL;
}
if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_ftm_params) +
(num_ch * sizeof(struct afe_sp_v4_channel_ftm_params)))) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
this_afe.spv4_th_vi_ftm_rcvd_param_size = param_hdr.param_size;
data_dest = (u32 *)&this_afe.spv4_th_vi_ftm_resp;
expected_size +=
@ -820,6 +862,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
break;
case AFE_PARAM_ID_SP_V4_TH_VI_V_VALI_PARAMS:
num_ch = data_start[0];
if (num_ch > SP_V2_NUM_MAX_SPKRS) {
pr_err("%s: Error: num_ch %d is greater than expected\n",
__func__,num_ch);
return -EINVAL;
}
if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_th_vi_v_vali_params) +
(num_ch *
sizeof(struct afe_sp_v4_channel_v_vali_params)))) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
this_afe.spv4_v_vali_rcvd_param_size = param_hdr.param_size;
data_dest = (u32 *)&this_afe.spv4_v_vali_resp;
expected_size +=
@ -829,6 +883,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
break;
case AFE_PARAM_ID_SP_V4_EX_VI_FTM_PARAMS:
num_ch = data_start[0];
if (num_ch > SP_V2_NUM_MAX_SPKRS) {
pr_err("%s: Error: num_ch %d is greater than expected\n",
__func__,num_ch);
return -EINVAL;
}
if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_ex_vi_ftm_params) +
(num_ch *
sizeof(struct afe_sp_v4_channel_ex_vi_ftm_params)))) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
this_afe.spv4_ex_vi_ftm_rcvd_param_size = param_hdr.param_size;
data_dest = (u32 *)&this_afe.spv4_ex_vi_ftm_resp;
expected_size +=
@ -837,6 +903,18 @@ static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
break;
case AFE_PARAM_ID_SP_V4_RX_TMAX_XMAX_LOGGING:
num_ch = data_start[0];
if (num_ch > SP_V2_NUM_MAX_SPKRS) {
pr_err("%s: Error: num_ch %d is greater than expected\n",
__func__,num_ch);
return -EINVAL;
}
if (param_hdr.param_size != (sizeof(struct afe_sp_v4_param_tmax_xmax_logging) +
(num_ch *
sizeof(struct afe_sp_v4_channel_tmax_xmax_params)))) {
pr_err("%s: Error: param_size %d is greater than expected\n",
__func__,param_hdr.param_size);
return -EINVAL;
}
this_afe.spv4_max_log_rcvd_param_size = param_hdr.param_size;
data_dest = (u32 *)&this_afe.spv4_max_log_resp;
expected_size +=

View file

@ -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 <linux/kernel.h>
@ -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]);
@ -474,6 +475,12 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
case AVCS_CMD_RSP_LOAD_MODULES:
pr_debug("%s: Received AVCS_CMD_RSP_LOAD_MODULES\n",
__func__);
if (data->payload_size != ((sizeof(struct avcs_load_unload_modules_sec_payload)
* rsp_payload->num_modules) + sizeof(uint32_t))) {
pr_err("%s: payload size greater than expected size %d\n",
__func__,data->payload_size);
return -EINVAL;
}
memcpy(rsp_payload, data->payload, data->payload_size);
q6core_lcl.avcs_module_resp_received = 1;
wake_up(&q6core_lcl.avcs_module_load_unload_wait);
@ -1036,6 +1043,8 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload
return -ENOMEM;
}
rsp_payload->num_modules = num_modules;
memcpy((uint8_t *)mod + sizeof(struct apr_hdr) +
sizeof(struct avcs_load_unload_modules_meminfo),
payload, payload_size);

View file

@ -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 <linux/slab.h>
#include <linux/kthread.h>
@ -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,