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

Commit 018c8a09 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "audioflinger: filter out reserved keys from setParameters()" into pi-dev

parents f2553690 f1047e87
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <cutils/multiuser.h>
#include <media/TimeCheck.h>
#include <private/android_filesystem_config.h>

@@ -904,8 +905,7 @@ status_t BnAudioFlinger::onTransact(
        case SET_MIC_MUTE:
        case SET_LOW_RAM_DEVICE:
        case SYSTEM_READY: {
            uid_t multiUserClientUid = IPCThreadState::self()->getCallingUid() % AID_USER_OFFSET;
            if (multiUserClientUid >= AID_APP_START) {
            if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
                      IPCThreadState::self()->getCallingUid());
+2 −3
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>

#include <cutils/multiuser.h>
#include <media/AudioEffect.h>
#include <media/IAudioPolicyService.h>
#include <media/TimeCheck.h>
@@ -875,8 +875,7 @@ status_t BnAudioPolicyService::onTransact(
        case SET_MASTER_MONO:
        case START_AUDIO_SOURCE:
        case STOP_AUDIO_SOURCE: {
            uid_t multiUserClientUid = IPCThreadState::self()->getCallingUid() % AID_USER_OFFSET;
            if (multiUserClientUid >= AID_APP_START) {
            if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
                      IPCThreadState::self()->getCallingUid());
+51 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <cutils/multiuser.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <binder/Parcel.h>
@@ -1178,16 +1179,59 @@ void AudioFlinger::broacastParametersToRecordThreads_l(const String8& keyValuePa
    }
}

// Filter reserved keys from setParameters() before forwarding to audio HAL or acting upon.
// Some keys are used for audio routing and audio path configuration and should be reserved for use
// by audio policy and audio flinger for functional, privacy and security reasons.
void AudioFlinger::filterReservedParameters(String8& keyValuePairs, uid_t callingUid)
{
    static const String8 kReservedParameters[] = {
        String8(AudioParameter::keyRouting),
        String8(AudioParameter::keySamplingRate),
        String8(AudioParameter::keyFormat),
        String8(AudioParameter::keyChannels),
        String8(AudioParameter::keyFrameCount),
        String8(AudioParameter::keyInputSource),
        String8(AudioParameter::keyMonoOutput),
        String8(AudioParameter::keyStreamConnect),
        String8(AudioParameter::keyStreamDisconnect),
        String8(AudioParameter::keyStreamSupportedFormats),
        String8(AudioParameter::keyStreamSupportedChannels),
        String8(AudioParameter::keyStreamSupportedSamplingRates),
    };

    // multiuser friendly app ID check for requests coming from audioserver
    if (multiuser_get_app_id(callingUid) == AID_AUDIOSERVER) {
        return;
    }

    AudioParameter param = AudioParameter(keyValuePairs);
    String8 value;
    for (auto& key : kReservedParameters) {
        if (param.get(key, value) == NO_ERROR) {
            ALOGW("%s: filtering key %s value %s from uid %d",
                  __func__, key.string(), value.string(), callingUid);
            param.remove(key);
        }
    }
    keyValuePairs = param.toString();
}

status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d",
            ioHandle, keyValuePairs.string(), IPCThreadState::self()->getCallingPid());
    ALOGV("setParameters(): io %d, keyvalue %s, calling pid %d calling uid %d",
            ioHandle, keyValuePairs.string(),
            IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());

    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

    String8 filteredKeyValuePairs = keyValuePairs;
    filterReservedParameters(filteredKeyValuePairs, IPCThreadState::self()->getCallingUid());

    ALOGV("%s: filtered keyvalue %s", __func__, filteredKeyValuePairs.string());

    // AUDIO_IO_HANDLE_NONE means the parameters are global to the audio hardware interface
    if (ioHandle == AUDIO_IO_HANDLE_NONE) {
        Mutex::Autolock _l(mLock);
@@ -1198,7 +1242,7 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
                sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
                status_t result = dev->setParameters(keyValuePairs);
                status_t result = dev->setParameters(filteredKeyValuePairs);
                // return success if at least one audio device accepts the parameters as not all
                // HALs are requested to support all parameters. If no audio device supports the
                // requested parameters, the last error is reported.
@@ -1209,7 +1253,7 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
            mHardwareStatus = AUDIO_HW_IDLE;
        }
        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
        AudioParameter param = AudioParameter(keyValuePairs);
        AudioParameter param = AudioParameter(filteredKeyValuePairs);
        String8 value;
        if (param.get(String8(AudioParameter::keyBtNrec), value) == NO_ERROR) {
            bool btNrecIsOff = (value == AudioParameter::valueOff);
@@ -1242,16 +1286,16 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
            }
        } else if (thread == primaryPlaybackThread_l()) {
            // indicate output device change to all input threads for pre processing
            AudioParameter param = AudioParameter(keyValuePairs);
            AudioParameter param = AudioParameter(filteredKeyValuePairs);
            int value;
            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
                    (value != 0)) {
                broacastParametersToRecordThreads_l(keyValuePairs);
                broacastParametersToRecordThreads_l(filteredKeyValuePairs);
            }
        }
    }
    if (thread != 0) {
        return thread->setParameters(keyValuePairs);
        return thread->setParameters(filteredKeyValuePairs);
    }
    return BAD_VALUE;
}
+2 −0
Original line number Diff line number Diff line
@@ -798,6 +798,8 @@ private:

    status_t    checkStreamType(audio_stream_type_t stream) const;

    void        filterReservedParameters(String8& keyValuePairs, uid_t callingUid);

#ifdef TEE_SINK
    // all record threads serially share a common tee sink, which is re-created on format change
    sp<NBAIO_Sink>   mRecordTeeSink;
+4 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <sys/time.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <cutils/multiuser.h>
#include <cutils/properties.h>
#include <binder/IPCThreadState.h>
#include <binder/ActivityManager.h>
@@ -274,7 +275,7 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
        const String8& regId, int32_t state)
{
    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
        mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
    }
}
@@ -284,7 +285,7 @@ void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
        audio_patch_handle_t patchHandle)
{
    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
                clientConfig, deviceConfig, patchHandle);
    }
@@ -577,7 +578,7 @@ void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled)
}

bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
    return uid % AID_USER_OFFSET < AID_APP_START;
    return multiuser_get_app_id(uid) < AID_APP_START;
}

void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {