Merge "dsp: adm: validate ADSP payload size before access"
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 03fa6a6..29d600f 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -1570,7 +1570,7 @@
}
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;
@@ -1592,6 +1592,15 @@
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]);
@@ -1710,9 +1719,16 @@
switch (data->opcode) {
case ADM_CMDRSP_DEVICE_OPEN_V5:
case ADM_CMDRSP_DEVICE_OPEN_V6: {
- struct adm_cmd_rsp_device_open_v5 *open =
- (struct adm_cmd_rsp_device_open_v5 *)data->payload;
+ struct adm_cmd_rsp_device_open_v5 *open = NULL;
+ 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);
@@ -1785,25 +1801,31 @@
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.stat
[port_idx][copp_idx], payload[0]);
wake_up(&this_adm.copp.wait[port_idx][copp_idx]);