msm: adm: validate ADSP payload size before access
Check the size of ADSP payload before accessing it. CRs-Fixed: 2380694 Change-Id: I52e74e5a86499ea61f8426f767948ce940d4d59c Signed-off-by: Vignesh Kulothungan <vigneshk@codeaurora.org>
This commit is contained in:
parent
acb7b45709
commit
41ec0b6adb
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2014, 2016, 2017 The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2014, 2016, 2017, 2019 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
|
||||
|
@ -1104,7 +1104,7 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
|||
}
|
||||
|
||||
adm_callback_debug_print(data);
|
||||
if (data->payload_size) {
|
||||
if (data->payload_size >= sizeof(uint32_t)) {
|
||||
copp_idx = (data->token) & 0XFF;
|
||||
port_idx = ((data->token) >> 16) & 0xFF;
|
||||
client_id = ((data->token) >> 8) & 0xFF;
|
||||
|
@ -1126,6 +1126,15 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
|||
if (data->opcode == APR_BASIC_RSP_RESULT) {
|
||||
pr_debug("%s: APR_BASIC_RSP_RESULT id 0x%x\n",
|
||||
__func__, payload[0]);
|
||||
if (!((client_id != ADM_CLIENT_ID_SOURCE_TRACKING) &&
|
||||
(payload[0] == ADM_CMD_SET_PP_PARAMS_V5))) {
|
||||
if (data->payload_size <
|
||||
(2 * sizeof(uint32_t))) {
|
||||
pr_err("%s: Invalid payload size %d\n",
|
||||
__func__, data->payload_size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (payload[1] != 0) {
|
||||
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
|
||||
__func__, payload[0], payload[1]);
|
||||
|
@ -1258,6 +1267,14 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
|||
struct adm_cmd_rsp_device_open_v5 *open =
|
||||
(struct adm_cmd_rsp_device_open_v5 *)data->payload;
|
||||
|
||||
if (data->payload_size <
|
||||
sizeof(struct adm_cmd_rsp_device_open_v5)) {
|
||||
pr_err("%s: Invalid payload size %d\n",
|
||||
__func__, data->payload_size);
|
||||
return 0;
|
||||
}
|
||||
open =
|
||||
(struct adm_cmd_rsp_device_open_v5 *)data->payload;
|
||||
if (open->copp_id == INVALID_COPP_ID) {
|
||||
pr_err("%s: invalid coppid rxed %d\n",
|
||||
__func__, open->copp_id);
|
||||
|
@ -1334,24 +1351,31 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
|
|||
pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST",
|
||||
__func__);
|
||||
pr_err(":err = 0x%x\n", payload[0]);
|
||||
} else if (payload[1] >
|
||||
((ADM_GET_TOPO_MODULE_LIST_LENGTH /
|
||||
sizeof(uint32_t)) - 1)) {
|
||||
pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST",
|
||||
__func__);
|
||||
pr_err(":size = %d\n", payload[1]);
|
||||
} else {
|
||||
idx = ADM_GET_TOPO_MODULE_LIST_LENGTH *
|
||||
copp_idx;
|
||||
pr_debug("%s:Num modules payload[1] %d\n",
|
||||
__func__, payload[1]);
|
||||
adm_module_topo_list[idx] = payload[1];
|
||||
for (i = 1; i <= payload[1]; i++) {
|
||||
adm_module_topo_list[idx+i] =
|
||||
payload[1+i];
|
||||
pr_debug("%s:payload[%d] = %x\n",
|
||||
__func__, (i+1), payload[1+i]);
|
||||
} else if (data->payload_size >=
|
||||
(2 * sizeof(uint32_t))) {
|
||||
if (payload[1] >
|
||||
((ADM_GET_TOPO_MODULE_LIST_LENGTH /
|
||||
sizeof(uint32_t)) - 1)) {
|
||||
pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST",
|
||||
__func__);
|
||||
pr_err(":size = %d\n", payload[1]);
|
||||
} else {
|
||||
idx = ADM_GET_TOPO_MODULE_LIST_LENGTH *
|
||||
copp_idx;
|
||||
pr_debug("%s:Num modules payload[1] %d\n",
|
||||
__func__, payload[1]);
|
||||
adm_module_topo_list[idx] = payload[1];
|
||||
for (i = 1; i <= payload[1]; i++) {
|
||||
adm_module_topo_list[idx+i] =
|
||||
payload[1+i];
|
||||
pr_debug("%s:payload[%d] = %x\n",
|
||||
__func__, (i+1),
|
||||
payload[1+i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: Invalid payload size %d\n",
|
||||
__func__, data->payload_size);
|
||||
}
|
||||
atomic_set(&this_adm.copp.cmd_err_code
|
||||
[port_idx][copp_idx], payload[0]);
|
||||
|
|
Loading…
Reference in New Issue