Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3cc95c4 authored by Varun Balaraj's avatar Varun Balaraj Committed by Gerrit - the friendly Code Review server
Browse files

audio: hal: Fix incorrect boundary check for interactive audio

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

Change-Id: I5887b28c576755ce44419691a371ee65a80ee714
parent fc9149ca
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -240,11 +240,12 @@ typedef struct mix_matrix_params {
    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 {
+80 −51
Original line number Diff line number Diff line
@@ -6305,12 +6305,7 @@ int platform_set_stream_pan_scale_params(void *platform,
    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 @@ int platform_set_stream_pan_scale_params(void *platform,
        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 @@ int platform_set_stream_downmix_params(void *platform,
    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 @@ int platform_set_stream_downmix_params(void *platform,
        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;

    downmix_param_data[length++] = mm_params.has_output_channel_map;
    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);

    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;
}

+68 −39
Original line number Diff line number Diff line
@@ -6123,7 +6123,7 @@ int platform_set_stream_pan_scale_params(void *platform,
    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 @@ int platform_set_stream_pan_scale_params(void *platform,
        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 @@ int platform_set_stream_downmix_params(void *platform,
    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 @@ int platform_set_stream_downmix_params(void *platform,
        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;

    downmix_param_data[length++] = mm_params.has_output_channel_map;
    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);

    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:
+2 −2
Original line number Diff line number Diff line
@@ -347,9 +347,9 @@ typedef struct qahw_mix_matrix_params {
    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;
+1 −1
Original line number Diff line number Diff line
@@ -1830,7 +1830,7 @@ audio_channel_mask_t get_channel_mask_for_name(char *name) {
    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;