Loading media/libaudioclient/IAudioFlinger.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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()); Loading media/libaudioclient/IAudioPolicyService.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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()); Loading services/audioflinger/AudioFlinger.cpp +51 −7 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading @@ -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. Loading @@ -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); Loading Loading @@ -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; } Loading services/audioflinger/AudioFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading services/audiopolicy/service/AudioPolicyService.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); } } Loading @@ -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); } Loading Loading @@ -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) { Loading Loading
media/libaudioclient/IAudioFlinger.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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()); Loading
media/libaudioclient/IAudioPolicyService.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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()); Loading
services/audioflinger/AudioFlinger.cpp +51 −7 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading @@ -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. Loading @@ -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); Loading Loading @@ -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; } Loading
services/audioflinger/AudioFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
services/audiopolicy/service/AudioPolicyService.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); } } Loading @@ -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); } Loading Loading @@ -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) { Loading