audio: hal: Fix incorrect boundary check for interactive audio

Fix incorrect boundary check for pan/scale/downmix controls.

Change-Id: I5887b28c576755ce44419691a371ee65a80ee714
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 4e5f4d8..7abc89b 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -240,11 +240,12 @@
     uint16_t num_output_channels;
     uint16_t num_input_channels;
     uint8_t has_output_channel_map;
-    uint32_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+    uint16_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
     uint8_t has_input_channel_map;
-    uint32_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+    uint16_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
     uint8_t has_mixer_coeffs;
-    float mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
+    /* member for coefficient gains in Q14 format */
+    uint32_t mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
 } mix_matrix_params_t;
 
 typedef union {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 6dfa0eb..e49ebe4 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -6305,12 +6305,7 @@
     int iter_i = 0;
     int iter_j = 0;
     int length = 0;
-    int pan_scale_data[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
-
-    if (sizeof(mm_params) > MAX_LENGTH_MIXER_CONTROL_IN_INT) {
-        ret = -EINVAL;
-        goto end;
-    }
+    char *pan_scale_data = NULL;
 
     snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                           "Audio Stream %d Pan Scale Control", snd_id);
@@ -6323,40 +6318,60 @@
         ret = -EINVAL;
         goto end;
     }
-    pan_scale_data[length++] = mm_params.num_output_channels;
-    pan_scale_data[length++] = mm_params.num_input_channels;
+    pan_scale_data = (char *) calloc(1, sizeof(mm_params));
+    if (!pan_scale_data) {
+        ret = -ENOMEM;
+        goto end;
+    }
+    memcpy(&pan_scale_data[length], &mm_params.num_output_channels,
+                              sizeof(mm_params.num_output_channels));
+    length += sizeof(mm_params.num_output_channels);
+    memcpy(&pan_scale_data[length], &mm_params.num_input_channels,
+                              sizeof(mm_params.num_input_channels));
+    length += sizeof(mm_params.num_input_channels);
 
-    pan_scale_data[length++] = mm_params.has_output_channel_map;
+    memcpy(&pan_scale_data[length], &mm_params.has_output_channel_map,
+                              sizeof(mm_params.has_output_channel_map));
+    length += sizeof(mm_params.has_output_channel_map);
     if (mm_params.has_output_channel_map &&
         mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_output_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            pan_scale_data[length++] = mm_params.output_channel_map[iter_i];
-    else {
+        mm_params.num_output_channels > 0) {
+        memcpy(&pan_scale_data[length], mm_params.output_channel_map,
+                (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+        length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
 
-    pan_scale_data[length++] = mm_params.has_input_channel_map;
+    memcpy(&pan_scale_data[length], &mm_params.has_input_channel_map,
+                                sizeof(mm_params.has_input_channel_map));
+    length += sizeof(mm_params.has_input_channel_map);
     if (mm_params.has_input_channel_map &&
         mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_input_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
-            pan_scale_data[length++] = mm_params.input_channel_map[iter_i];
-    else {
+        mm_params.num_input_channels > 0) {
+        memcpy(&pan_scale_data[length], mm_params.input_channel_map,
+               (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+            length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
-
-    pan_scale_data[length++] = mm_params.has_mixer_coeffs;
+    pan_scale_data[length] = mm_params.has_mixer_coeffs;
+    length += sizeof(mm_params.has_mixer_coeffs);
     if (mm_params.has_mixer_coeffs)
         for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
-                pan_scale_data[length++] =
-                                    mm_params.mixer_coeffs[iter_i][iter_j];
+            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+                 memcpy(&pan_scale_data[length],
+                        &mm_params.mixer_coeffs[iter_i][iter_j],
+                        (sizeof(mm_params.mixer_coeffs[0][0])));
+                 length += (sizeof(mm_params.mixer_coeffs[0][0]));
+            }
 
     ret = mixer_ctl_set_array(ctl, pan_scale_data, length);
 end:
+    if (pan_scale_data)
+        free(pan_scale_data);
     return ret;
 }
 
@@ -6369,20 +6384,13 @@
     struct audio_device *adev = my_data->adev;
     struct mixer_ctl *ctl;
     char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
-    int downmix_param_data[MAX_LENGTH_MIXER_CONTROL_IN_INT] = {0};
+    char *downmix_param_data = NULL;
     int ret = 0;
     int iter_i = 0;
     int iter_j = 0;
     int length = 0;
     int be_idx = 0;
 
-    if ((sizeof(mm_params) +
-         sizeof(be_idx)) >
-        MAX_LENGTH_MIXER_CONTROL_IN_INT) {
-        ret = -EINVAL;
-        goto end;
-    }
-
     snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                           "Audio Device %d Downmix Control", snd_id);
     ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
@@ -6392,45 +6400,66 @@
         ALOGE("%s: Could not get ctl for mixer cmd - %s",
               __func__, mixer_ctl_name);
         ret = -EINVAL;
-        goto end;
     }
 
+    downmix_param_data = (char *) calloc(1, sizeof(mm_params) + sizeof(be_idx));
+    if (!downmix_param_data) {
+        ret = -ENOMEM;
+        goto end;
+    }
     be_idx = platform_get_snd_device_backend_index(snd_device);
-    downmix_param_data[length]   = be_idx;
-    downmix_param_data[length++] = mm_params.num_output_channels;
-    downmix_param_data[length++] = mm_params.num_input_channels;
+    memcpy(&downmix_param_data[length], &be_idx, sizeof(be_idx));
+    length += sizeof(be_idx);
+    memcpy(&downmix_param_data[length], &mm_params.num_output_channels,
+                                    sizeof(mm_params.num_output_channels));
+    length += sizeof(mm_params.num_output_channels);
+    memcpy(&downmix_param_data[length], &mm_params.num_input_channels,
+                                    sizeof(mm_params.num_input_channels));
+    length += sizeof(mm_params.num_input_channels);
 
-    downmix_param_data[length++] = mm_params.has_output_channel_map;
+    memcpy(&downmix_param_data[length], &mm_params.has_output_channel_map,
+                                   sizeof(mm_params.has_output_channel_map));
+    length += sizeof(mm_params.has_output_channel_map);
     if (mm_params.has_output_channel_map &&
         mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_output_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            downmix_param_data[length++] = mm_params.output_channel_map[iter_i];
-    else {
+        mm_params.num_output_channels > 0) {
+        memcpy(&downmix_param_data[length], mm_params.output_channel_map,
+                (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+        length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
 
-    downmix_param_data[length++] = mm_params.has_input_channel_map;
+    memcpy(&downmix_param_data[length], &mm_params.has_input_channel_map,
+                                   sizeof(mm_params.has_input_channel_map));
+    length += sizeof(mm_params.has_input_channel_map);
     if (mm_params.has_input_channel_map &&
         mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_input_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
-            downmix_param_data[length++] = mm_params.input_channel_map[iter_i];
-    else {
+        mm_params.num_input_channels > 0) {
+        memcpy(&downmix_param_data[length], mm_params.input_channel_map,
+                (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+            length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
-
-    downmix_param_data[length++] = mm_params.has_mixer_coeffs;
+    memcpy(&downmix_param_data[length], &mm_params.has_mixer_coeffs,
+                                    sizeof(mm_params.has_mixer_coeffs));
+    length += sizeof(mm_params.has_mixer_coeffs);
     if (mm_params.has_mixer_coeffs)
         for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
-                downmix_param_data[length++] =
-                                       mm_params.mixer_coeffs[iter_i][iter_j];
+            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+                memcpy((uint32_t *) &downmix_param_data[length],
+                        &mm_params.mixer_coeffs[iter_i][iter_j],
+                        (sizeof(mm_params.mixer_coeffs[0][0])));
+                length += (sizeof(mm_params.mixer_coeffs[0][0]));
+            }
 
     ret = mixer_ctl_set_array(ctl, downmix_param_data, length);
 end:
+    if (downmix_param_data)
+        free(downmix_param_data);
     return ret;
 }
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 61ef223..f24332e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -6123,7 +6123,7 @@
     int iter_i = 0;
     int iter_j = 0;
     int length = 0;
-    int *pan_scale_data = NULL;
+    char *pan_scale_data = NULL;
 
     snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                           "Audio Stream %d Pan Scale Control", snd_id);
@@ -6136,41 +6136,55 @@
         ret = -EINVAL;
         goto end;
     }
-    pan_scale_data = (int* ) calloc(1, sizeof(mm_params));
+    pan_scale_data = (char *) calloc(1, sizeof(mm_params));
     if (!pan_scale_data) {
         ret = -ENOMEM;
         goto end;
     }
-    pan_scale_data[length++] = mm_params.num_output_channels;
-    pan_scale_data[length++] = mm_params.num_input_channels;
+    memcpy(&pan_scale_data[length], &mm_params.num_output_channels,
+                              sizeof(mm_params.num_output_channels));
+    length += sizeof(mm_params.num_output_channels);
+    memcpy(&pan_scale_data[length], &mm_params.num_input_channels,
+                              sizeof(mm_params.num_input_channels));
+    length += sizeof(mm_params.num_input_channels);
 
-    pan_scale_data[length++] = mm_params.has_output_channel_map;
+    memcpy(&pan_scale_data[length], &mm_params.has_output_channel_map,
+                              sizeof(mm_params.has_output_channel_map));
+    length += sizeof(mm_params.has_output_channel_map);
     if (mm_params.has_output_channel_map &&
         mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_output_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            pan_scale_data[length++] = mm_params.output_channel_map[iter_i];
-    else {
+        mm_params.num_output_channels > 0) {
+        memcpy(&pan_scale_data[length], mm_params.output_channel_map,
+                (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+        length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
 
-    pan_scale_data[length++] = mm_params.has_input_channel_map;
+    memcpy(&pan_scale_data[length], &mm_params.has_input_channel_map,
+                                sizeof(mm_params.has_input_channel_map));
+    length += sizeof(mm_params.has_input_channel_map);
     if (mm_params.has_input_channel_map &&
         mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_input_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
-            pan_scale_data[length++] = mm_params.input_channel_map[iter_i];
-    else {
+        mm_params.num_input_channels > 0) {
+        memcpy(&pan_scale_data[length], mm_params.input_channel_map,
+               (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+            length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
-    pan_scale_data[length++] = mm_params.has_mixer_coeffs;
+    pan_scale_data[length] = mm_params.has_mixer_coeffs;
+    length += sizeof(mm_params.has_mixer_coeffs);
     if (mm_params.has_mixer_coeffs)
         for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
-                pan_scale_data[length++] =
-                                    mm_params.mixer_coeffs[iter_i][iter_j];
+            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+                 memcpy(&pan_scale_data[length],
+                        &mm_params.mixer_coeffs[iter_i][iter_j],
+                        (sizeof(mm_params.mixer_coeffs[0][0])));
+                 length += (sizeof(mm_params.mixer_coeffs[0][0]));
+            }
 
     ret = mixer_ctl_set_array(ctl, pan_scale_data, length);
 end:
@@ -6188,7 +6202,7 @@
     struct audio_device *adev = my_data->adev;
     struct mixer_ctl *ctl;
     char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
-    int *downmix_param_data = NULL;
+    char *downmix_param_data = NULL;
     int ret = 0;
     int iter_i = 0;
     int iter_j = 0;
@@ -6206,44 +6220,59 @@
         ret = -EINVAL;
     }
 
-    downmix_param_data = (int* ) calloc(1, sizeof(mm_params) + sizeof(be_idx));
+    downmix_param_data = (char *) calloc(1, sizeof(mm_params) + sizeof(be_idx));
     if (!downmix_param_data) {
         ret = -ENOMEM;
         goto end;
     }
     be_idx = platform_get_snd_device_backend_index(snd_device);
-    downmix_param_data[length++] = be_idx;
-    downmix_param_data[length++] = mm_params.num_output_channels;
-    downmix_param_data[length++] = mm_params.num_input_channels;
+    memcpy(&downmix_param_data[length], &be_idx, sizeof(be_idx));
+    length += sizeof(be_idx);
+    memcpy(&downmix_param_data[length], &mm_params.num_output_channels,
+                                    sizeof(mm_params.num_output_channels));
+    length += sizeof(mm_params.num_output_channels);
+    memcpy(&downmix_param_data[length], &mm_params.num_input_channels,
+                                    sizeof(mm_params.num_input_channels));
+    length += sizeof(mm_params.num_input_channels);
 
-    downmix_param_data[length++] = mm_params.has_output_channel_map;
+    memcpy(&downmix_param_data[length], &mm_params.has_output_channel_map,
+                                   sizeof(mm_params.has_output_channel_map));
+    length += sizeof(mm_params.has_output_channel_map);
     if (mm_params.has_output_channel_map &&
         mm_params.num_output_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_output_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            downmix_param_data[length++] = mm_params.output_channel_map[iter_i];
-    else {
+        mm_params.num_output_channels > 0) {
+        memcpy(&downmix_param_data[length], mm_params.output_channel_map,
+                (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0])));
+        length += (mm_params.num_output_channels * sizeof(mm_params.output_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
 
-    downmix_param_data[length++] = mm_params.has_input_channel_map;
+    memcpy(&downmix_param_data[length], &mm_params.has_input_channel_map,
+                                   sizeof(mm_params.has_input_channel_map));
+    length += sizeof(mm_params.has_input_channel_map);
     if (mm_params.has_input_channel_map &&
         mm_params.num_input_channels <= MAX_CHANNELS_SUPPORTED &&
-        mm_params.num_input_channels > 0)
-        for (iter_i = 0; iter_i < mm_params.num_input_channels; iter_i++)
-            downmix_param_data[length++] = mm_params.input_channel_map[iter_i];
-    else {
+        mm_params.num_input_channels > 0) {
+        memcpy(&downmix_param_data[length], mm_params.input_channel_map,
+                (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0])));
+            length += (mm_params.num_input_channels * sizeof(mm_params.input_channel_map[0]));
+    } else {
         ret = -EINVAL;
         goto end;
     }
-
-    downmix_param_data[length++] = mm_params.has_mixer_coeffs;
+    memcpy(&downmix_param_data[length], &mm_params.has_mixer_coeffs,
+                                    sizeof(mm_params.has_mixer_coeffs));
+    length += sizeof(mm_params.has_mixer_coeffs);
     if (mm_params.has_mixer_coeffs)
         for (iter_i = 0; iter_i < mm_params.num_output_channels; iter_i++)
-            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++)
-                downmix_param_data[length++] =
-                                       mm_params.mixer_coeffs[iter_i][iter_j];
+            for (iter_j = 0; iter_j < mm_params.num_input_channels; iter_j++) {
+                memcpy((uint32_t *) &downmix_param_data[length],
+                        &mm_params.mixer_coeffs[iter_i][iter_j],
+                        (sizeof(mm_params.mixer_coeffs[0][0])));
+                length += (sizeof(mm_params.mixer_coeffs[0][0]));
+            }
 
     ret = mixer_ctl_set_array(ctl, downmix_param_data, length);
 end:
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index c13a1a4..a301bf9 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -347,9 +347,9 @@
     uint16_t num_output_channels;
     uint16_t num_input_channels;
     uint8_t has_output_channel_map;
-    uint32_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+    uint16_t output_channel_map[AUDIO_CHANNEL_COUNT_MAX];
     uint8_t has_input_channel_map;
-    uint32_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
+    uint16_t input_channel_map[AUDIO_CHANNEL_COUNT_MAX];
     uint8_t has_mixer_coeffs;
     float mixer_coeffs[AUDIO_CHANNEL_COUNT_MAX][AUDIO_CHANNEL_COUNT_MAX];
 } qahw_mix_matrix_params_t;
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index 1338591..0a2da4d 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -1830,7 +1830,7 @@
     return channel_type;
 }
 
-int extract_channel_mapping(uint32_t *channel_map, const char * arg_string){
+int extract_channel_mapping(uint16_t *channel_map, const char * arg_string){
 
     char *token_string = NULL;
     char *init_ptr = NULL;