Commit message: None
CVE: CVE-2017-0812
CWE: CWE-125
Vulnerability description: An elevation of privilege vulnerability in the Android media framework (audio hal). Product: Android. Versions: 7.0, 7.1.1, 7.1.2, 8.0. Android ID: A-62873231.

Project: Android

static int adev_get_master_volume(struct audio_hw_device *dev,
 float *volume)
{
 (void)dev;
 (void)volume;

 return -ENOSYS;
}

Project: Android

static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
{
 struct audio_device *adev = (struct audio_device *)dev;
 int err = 0;

    pthread_mutex_lock(&adev->lock);
    adev->mic_mute = state;

 if (adev->mode == AUDIO_MODE_IN_CALL) {
 /* TODO */
 }

    pthread_mutex_unlock(&adev->lock);
 return err;
}

Project: Android

static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
{
 struct audio_device *adev = (struct audio_device *)dev;

    pthread_mutex_lock(&adev->lock);
 if (adev->mode != mode) {
        ALOGI("%s mode = %d", __func__, mode);
        adev->mode = mode;
 }
    pthread_mutex_unlock(&adev->lock);
 return 0;
}

Project: Android

static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
 audio_usecase_t uc_id)
{
 struct audio_usecase *usecase;
 struct listnode *node;

    list_for_each(node, &adev->usecase_list) {
        usecase = node_to_item(node, struct audio_usecase, adev_list_node);
 if (usecase->id == uc_id)
 return usecase;
 }
 return NULL;
}

Project: Android

static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
 usecase_type_t type)
{
 struct audio_usecase *usecase;
 struct listnode *node;

    list_for_each(node, &adev->usecase_list) {
        usecase = node_to_item(node, struct audio_usecase, adev_list_node);
 if (usecase->type & type)
 return usecase;
 }
 return NULL;
}

Project: Android

static int in_standby(struct audio_stream *stream)
{
 struct stream_in *in = (struct stream_in *)stream;
 struct audio_device *adev = in->dev;
 int status;
    ALOGV("%s: enter", __func__);
    pthread_mutex_lock(&adev->lock_inputs);
    status = in_standby_l(in);
    pthread_mutex_unlock(&adev->lock_inputs);
    ALOGV("%s: exit:  status(%d)", __func__, status);
 return status;
}

Project: Android

static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
{
 (void)stream;
 (void)effect;
 return 0;
}

Project: Android

static void release_buffer(struct resampler_buffer_provider *buffer_provider,
 struct resampler_buffer* buffer)
{
 struct stream_in *in;

 if (buffer_provider == NULL || buffer == NULL)
 return;

    in = (struct stream_in *)((char *)buffer_provider -
                                   offsetof(struct stream_in, buf_provider));

    in->read_buf_frames -= buffer->frame_count;
}

Project: Android

static int start_voice_call(struct audio_device *adev)
{
 struct audio_usecase *uc_info;

    ALOGV("%s: enter", __func__);

    uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
    uc_info->id = USECASE_VOICE_CALL;
    uc_info->type = VOICE_CALL;
    uc_info->stream = (struct audio_stream *)adev->primary_output;
    uc_info->devices = adev->primary_output->devices;
    uc_info->in_snd_device = SND_DEVICE_NONE;
    uc_info->out_snd_device = SND_DEVICE_NONE;

    uc_select_pcm_devices(uc_info);

    list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);

    select_devices(adev, USECASE_VOICE_CALL);


 /* TODO: implement voice call start */

 /* set cached volume */
    set_voice_volume_l(adev, adev->voice_volume);

    adev->in_call = true;
    ALOGV("%s: exit", __func__);
 return 0;
}