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

gugelfrei
TreeHugger Robot 6 years ago committed by Android (Google) Code Review
commit 018c8a09a3

@ -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());

@ -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());

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

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

@ -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) {

Loading…
Cancel
Save