summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-05-05 19:22:03 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-05-05 19:22:02 -0700
commit43808cc02cbcda4ca970e32e7b2d5f71c0d033d5 (patch)
tree0d9a95302ebba8363b2297b4cb397c6d9f8a6e9a
parentf4d62ca185dd067aec1a6ebf14375abfb95aa935 (diff)
parent5b134f53b323a96ba909c272341a53a1ed010cab (diff)
Merge "msm: adm: validate ADSP payload size before access"
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index ab5af74ec0c0..5478920e38a9 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -1230,12 +1230,22 @@ static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
switch (opcode) {
case ADM_CMDRSP_GET_PP_PARAMS_V5:
struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5);
+ if (payload_size < struct_size) {
+ pr_err("%s: payload size %d < expected size %d\n",
+ __func__, payload_size, struct_size);
+ break;
+ }
v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload;
data_size = v5_rsp->param_hdr.param_size;
param_data = v5_rsp->param_data;
break;
case ADM_CMDRSP_GET_PP_PARAMS_V6:
struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6);
+ if (payload_size < struct_size) {
+ pr_err("%s: payload size %d < expected size %d\n",
+ __func__, payload_size, struct_size);
+ break;
+ }
v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload;
data_size = v6_rsp->param_hdr.param_size;
param_data = v6_rsp->param_data;
@@ -1399,7 +1409,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;
@@ -1421,6 +1431,16 @@ 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) ||
+ (payload[0] == ADM_CMD_SET_PP_PARAMS_V6)))) {
+ 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]);
@@ -1545,9 +1565,16 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
case ADM_CMDRSP_DEVICE_OPEN_V5:
case ADM_CMDRSP_DEVICE_OPEN_V6:
case ADM_CMDRSP_DEVICE_OPEN_V8: {
- 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);
@@ -1603,21 +1630,28 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv)
case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2:
pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n",
__func__);
- num_modules = payload[1];
- pr_debug("%s: Num modules %d\n", __func__, num_modules);
- if (payload[0]) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
- __func__, payload[0]);
- } else if (num_modules > MAX_MODULES_IN_TOPO) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
- __func__, num_modules);
+ if (data->payload_size >= (2 * sizeof(uint32_t))) {
+ num_modules = payload[1];
+ pr_debug("%s: Num modules %d\n", __func__,
+ num_modules);
+ if (payload[0]) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
+ __func__, payload[0]);
+ } else if (num_modules > MAX_MODULES_IN_TOPO) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
+ __func__, num_modules);
+ } else {
+ ret = adm_process_get_topo_list_response
+ (data->opcode, copp_idx,
+ num_modules, payload,
+ data->payload_size);
+ if (ret)
+ pr_err("%s: Failed to process get topo modules list response, error %d\n",
+ __func__, ret);
+ }
} else {
- ret = adm_process_get_topo_list_response(
- data->opcode, copp_idx, num_modules,
- payload, data->payload_size);
- if (ret)
- pr_err("%s: Failed to process get topo modules list response, error %d\n",
- __func__, ret);
+ pr_err("%s: Invalid payload size %d\n",
+ __func__, data->payload_size);
}
atomic_set(&this_adm.copp.stat[port_idx][copp_idx],
payload[0]);