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:
Vignesh Kulothungan 2019-02-28 13:12:28 -08:00 committed by syphyr
parent acb7b45709
commit 41ec0b6adb
1 changed files with 43 additions and 19 deletions

View File

@ -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]);