Loading services/audioflinger/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,7 @@ cc_library { ], static_libs: [ "audiopermissioncontroller", "libcpustats", "libpermission", ], Loading services/audioflinger/AudioFlinger.cpp +198 −87 Original line number Diff line number Diff line Loading @@ -39,13 +39,17 @@ #include <binder/IServiceManager.h> #include <binder/Parcel.h> #include <cutils/properties.h> #include <com_android_media_audio.h> #include <com_android_media_audioserver.h> #include <media/AidlConversion.h> #include <media/AudioParameter.h> #include <media/AudioValidator.h> #include <media/IMediaLogService.h> #include <media/IPermissionProvider.h> #include <media/MediaMetricsItem.h> #include <media/NativePermissionController.h> #include <media/TypeConverter.h> #include <media/ValidatedAttributionSourceState.h> #include <mediautils/BatteryNotifier.h> #include <mediautils/MemoryLeakTrackUtil.h> #include <mediautils/MethodStatistics.h> Loading Loading @@ -81,12 +85,17 @@ namespace android { using ::android::base::StringPrintf; using aidl_utils::statusTFromBinderStatus; using media::IEffectClient; using media::audio::common::AudioMMapPolicyInfo; using media::audio::common::AudioMMapPolicyType; using media::audio::common::AudioMode; using android::content::AttributionSourceState; using android::detail::AudioHalVersionInfo; using com::android::media::permission::INativePermissionController; using com::android::media::permission::IPermissionProvider; using com::android::media::permission::NativePermissionController; using com::android::media::permission::ValidatedAttributionSourceState; static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion = AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1); Loading Loading @@ -118,6 +127,52 @@ static void sMediaLogInit() } } static error::BinderResult<ValidatedAttributionSourceState> validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr, const IPermissionProvider& provider) { const auto callingUid = IPCThreadState::self()->getCallingUid(); // We trust the following UIDs to appropriate validated identities above us if (isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { // Legacy paths may not properly populate package name, so we attempt to handle. if (!attr.packageName.has_value() || attr.packageName.value() == "") { ALOGW("Trusted client %d provided attr with missing package name" , callingUid); attr.packageName = VALUE_OR_RETURN(provider.getPackagesForUid(callingUid))[0]; } // Behavior change: In the case of delegation, if pid is invalid, // filling it in with the callingPid will cause a mismatch between the // pid and the uid in the attribution, which is error-prone. // Instead, assert that the pid from a trusted source is valid if (attr.pid == -1) { if (callingUid != static_cast<uid_t>(attr.uid)) { return error::unexpectedExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT, "validateAttribution: Invalid pid from delegating trusted source"); } else { // Legacy handling for trusted clients which may not fill pid correctly attr.pid = IPCThreadState::self()->getCallingPid(); } } return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr)); } else { // Behavior change: Populate pid with callingPid unconditionally. Previously, we // allowed caller provided pid, if uid matched calling context, but this is error-prone // since it allows mismatching uid/pid return ValidatedAttributionSourceState::createFromBinderContext(std::move(attr), provider); } } #define VALUE_OR_RETURN_CONVERTED(exp) \ ({ \ auto _tmp = (exp); \ if (!_tmp.ok()) { \ ALOGE("Function: %s Line: %d Failed result (%s)", __FUNCTION__, __LINE__, \ errorToString(_tmp.error()).c_str()); \ return statusTFromBinderStatus(_tmp.error()); \ } \ std::move(_tmp.value()); \ }) // Creates association between Binder code to name for IAudioFlinger. #define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \ BINDER_METHOD_ENTRY(createTrack) \ Loading Loading @@ -519,19 +574,22 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di audio_attributes_t localAttr = *attr; // TODO b/182392553: refactor or make clearer AttributionSourceState adjAttributionSource; if (!com::android::media::audio::audioserver_permissions()) { pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); AttributionSourceState adjAttributionSource = client.attributionSource; adjAttributionSource = client.attributionSource; if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid)); ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); updatePid = true; } if (updatePid) { Loading @@ -539,10 +597,19 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, clientPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(client.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } if (direction == MmapStreamInterface::DIRECTION_OUTPUT) { audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER; Loading Loading @@ -997,37 +1064,51 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, bool isSpatialized = false; bool isBitPerfect = false; // TODO b/182392553: refactor or make clearer pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(input.clientInfo.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(input.clientInfo.attributionSource.uid)); audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE; std::vector<int> effectIds; audio_attributes_t localAttr = input.attr; AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource; AttributionSourceState adjAttributionSource; pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = input.clientInfo.attributionSource; const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t( input.clientInfo.attributionSource.uid)); pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t( input.clientInfo.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); clientUid = callingUid; updatePid = true; } const pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (updatePid) { ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, clientPid); clientPid = callingPid; adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(input.clientInfo.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } audio_session_t sessionId = input.sessionId; if (sessionId == AUDIO_SESSION_ALLOCATE) { sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); Loading Loading @@ -1079,7 +1160,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, goto Exit; } client = registerPid(clientPid); client = registerPid(adjAttributionSource.pid); IAfPlaybackThread* effectThread = nullptr; sp<IAfEffectChain> effectChain = nullptr; Loading Loading @@ -2199,6 +2280,12 @@ void AudioFlinger::onHardError(std::set<audio_port_handle_t>& trackPortIds) { } } const IPermissionProvider& AudioFlinger::getPermissionProvider() { // This is inited as part of service construction, prior to binder registration, // so it should always be non-null. return mAudioPolicyServiceLocal.load()->getPermissionProvider(); } // removeClient_l() must be called with AudioFlinger::clientMutex() held void AudioFlinger::removeClient_l(pid_t pid) { Loading Loading @@ -2308,8 +2395,10 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, output.buffers.clear(); output.inputId = AUDIO_IO_HANDLE_NONE; // TODO b/182392553: refactor or clean up AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource; AttributionSourceState adjAttributionSource; pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = input.clientInfo.attributionSource; bool updatePid = (adjAttributionSource.pid == -1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t( Loading @@ -2318,20 +2407,31 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, ALOGW_IF(currentUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, currentUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); updatePid = true; } const pid_t callingPid = IPCThreadState::self()->getCallingPid(); const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t( adjAttributionSource.pid)); if (updatePid) { ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, currentPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller( input.clientInfo.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } // further format checks are performed by createRecordTrack_l() if (!audio_is_valid_format(input.config.format)) { ALOGE("createRecord() invalid format %#x", input.config.format); Loading Loading @@ -4121,20 +4221,31 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, int idOut = -1; status_t lStatus = NO_ERROR; // TODO b/182392553: refactor or make clearer const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t callingUid = IPCThreadState::self()->getCallingUid(); pid_t currentPid; if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid)); currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid)); if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { const pid_t callingPid = IPCThreadState::self()->getCallingPid(); ALOGW_IF(currentPid != -1 && currentPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, currentPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); currentPid = callingPid; } adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(request.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); currentPid = adjAttributionSource.pid; } ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p", adjAttributionSource.pid, effectClient.get(), priority, sessionId, io, Loading services/audioflinger/AudioFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,8 @@ private: void onHardError(std::set<audio_port_handle_t>& trackPortIds) final EXCLUDES_AudioFlinger_ClientMutex; const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() final; // ---- end of IAfThreadCallback interface /* List available audio ports and their attributes */ Loading services/audioflinger/IAfThread.h +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,10 @@ #include <optional> namespace com::android::media::permission { class IPermissionProvider; } namespace android { class IAfDirectOutputThread; Loading Loading @@ -122,6 +126,9 @@ public: EXCLUDES_AudioFlinger_ClientMutex = 0; virtual void onHardError(std::set<audio_port_handle_t>& trackPortIds) = 0; virtual const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() = 0; }; class IAfThreadBase : public virtual RefBase { Loading services/audioflinger/Threads.cpp +20 −2 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ #include <media/nbaio/Pipe.h> #include <media/nbaio/PipeReader.h> #include <media/nbaio/SourceAudioBufferProvider.h> #include <media/ValidatedAttributionSourceState.h> #include <mediautils/BatteryNotifier.h> #include <mediautils/Process.h> #include <mediautils/SchedulingPolicyService.h> Loading Loading @@ -120,6 +121,8 @@ static inline T min(const T& a, const T& b) return a < b ? a : b; } using com::android::media::permission::ValidatedAttributionSourceState; namespace android { using audioflinger::SyncEvent; Loading Loading @@ -10302,8 +10305,23 @@ status_t MmapThread::start(const AudioClient& client, audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE; audio_io_handle_t io = mId; const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage( AttributionSourceState adjAttributionSource; if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = afutils::checkAttributionSourcePackage( client.attributionSource); } else { // TODO(b/342475009) validate in oboeservice, and plumb downwards auto validatedRes = ValidatedAttributionSourceState::createFromTrustedUidNoPackage( client.attributionSource, mAfThreadCallback->getPermissionProvider() ); if (!validatedRes.has_value()) { ALOGE("MMAP client package validation fail: %s", validatedRes.error().toString8().c_str()); return aidl_utils::statusTFromBinderStatus(validatedRes.error()); } adjAttributionSource = std::move(validatedRes.value()).unwrapInto(); } const auto localSessionId = mSessionId; auto localAttr = mAttr; Loading Loading
services/audioflinger/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,7 @@ cc_library { ], static_libs: [ "audiopermissioncontroller", "libcpustats", "libpermission", ], Loading
services/audioflinger/AudioFlinger.cpp +198 −87 Original line number Diff line number Diff line Loading @@ -39,13 +39,17 @@ #include <binder/IServiceManager.h> #include <binder/Parcel.h> #include <cutils/properties.h> #include <com_android_media_audio.h> #include <com_android_media_audioserver.h> #include <media/AidlConversion.h> #include <media/AudioParameter.h> #include <media/AudioValidator.h> #include <media/IMediaLogService.h> #include <media/IPermissionProvider.h> #include <media/MediaMetricsItem.h> #include <media/NativePermissionController.h> #include <media/TypeConverter.h> #include <media/ValidatedAttributionSourceState.h> #include <mediautils/BatteryNotifier.h> #include <mediautils/MemoryLeakTrackUtil.h> #include <mediautils/MethodStatistics.h> Loading Loading @@ -81,12 +85,17 @@ namespace android { using ::android::base::StringPrintf; using aidl_utils::statusTFromBinderStatus; using media::IEffectClient; using media::audio::common::AudioMMapPolicyInfo; using media::audio::common::AudioMMapPolicyType; using media::audio::common::AudioMode; using android::content::AttributionSourceState; using android::detail::AudioHalVersionInfo; using com::android::media::permission::INativePermissionController; using com::android::media::permission::IPermissionProvider; using com::android::media::permission::NativePermissionController; using com::android::media::permission::ValidatedAttributionSourceState; static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion = AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1); Loading Loading @@ -118,6 +127,52 @@ static void sMediaLogInit() } } static error::BinderResult<ValidatedAttributionSourceState> validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr, const IPermissionProvider& provider) { const auto callingUid = IPCThreadState::self()->getCallingUid(); // We trust the following UIDs to appropriate validated identities above us if (isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { // Legacy paths may not properly populate package name, so we attempt to handle. if (!attr.packageName.has_value() || attr.packageName.value() == "") { ALOGW("Trusted client %d provided attr with missing package name" , callingUid); attr.packageName = VALUE_OR_RETURN(provider.getPackagesForUid(callingUid))[0]; } // Behavior change: In the case of delegation, if pid is invalid, // filling it in with the callingPid will cause a mismatch between the // pid and the uid in the attribution, which is error-prone. // Instead, assert that the pid from a trusted source is valid if (attr.pid == -1) { if (callingUid != static_cast<uid_t>(attr.uid)) { return error::unexpectedExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT, "validateAttribution: Invalid pid from delegating trusted source"); } else { // Legacy handling for trusted clients which may not fill pid correctly attr.pid = IPCThreadState::self()->getCallingPid(); } } return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr)); } else { // Behavior change: Populate pid with callingPid unconditionally. Previously, we // allowed caller provided pid, if uid matched calling context, but this is error-prone // since it allows mismatching uid/pid return ValidatedAttributionSourceState::createFromBinderContext(std::move(attr), provider); } } #define VALUE_OR_RETURN_CONVERTED(exp) \ ({ \ auto _tmp = (exp); \ if (!_tmp.ok()) { \ ALOGE("Function: %s Line: %d Failed result (%s)", __FUNCTION__, __LINE__, \ errorToString(_tmp.error()).c_str()); \ return statusTFromBinderStatus(_tmp.error()); \ } \ std::move(_tmp.value()); \ }) // Creates association between Binder code to name for IAudioFlinger. #define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \ BINDER_METHOD_ENTRY(createTrack) \ Loading Loading @@ -519,19 +574,22 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di audio_attributes_t localAttr = *attr; // TODO b/182392553: refactor or make clearer AttributionSourceState adjAttributionSource; if (!com::android::media::audio::audioserver_permissions()) { pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); AttributionSourceState adjAttributionSource = client.attributionSource; adjAttributionSource = client.attributionSource; if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid)); ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); updatePid = true; } if (updatePid) { Loading @@ -539,10 +597,19 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, clientPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(client.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } if (direction == MmapStreamInterface::DIRECTION_OUTPUT) { audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER; Loading Loading @@ -997,37 +1064,51 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, bool isSpatialized = false; bool isBitPerfect = false; // TODO b/182392553: refactor or make clearer pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(input.clientInfo.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(input.clientInfo.attributionSource.uid)); audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE; std::vector<int> effectIds; audio_attributes_t localAttr = input.attr; AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource; AttributionSourceState adjAttributionSource; pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = input.clientInfo.attributionSource; const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t( input.clientInfo.attributionSource.uid)); pid_t clientPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t( input.clientInfo.attributionSource.pid)); bool updatePid = (clientPid == (pid_t)-1); if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { ALOGW_IF(clientUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); clientUid = callingUid; updatePid = true; } const pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (updatePid) { ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, clientPid); clientPid = callingPid; adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(input.clientInfo.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } audio_session_t sessionId = input.sessionId; if (sessionId == AUDIO_SESSION_ALLOCATE) { sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION); Loading Loading @@ -1079,7 +1160,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input, goto Exit; } client = registerPid(clientPid); client = registerPid(adjAttributionSource.pid); IAfPlaybackThread* effectThread = nullptr; sp<IAfEffectChain> effectChain = nullptr; Loading Loading @@ -2199,6 +2280,12 @@ void AudioFlinger::onHardError(std::set<audio_port_handle_t>& trackPortIds) { } } const IPermissionProvider& AudioFlinger::getPermissionProvider() { // This is inited as part of service construction, prior to binder registration, // so it should always be non-null. return mAudioPolicyServiceLocal.load()->getPermissionProvider(); } // removeClient_l() must be called with AudioFlinger::clientMutex() held void AudioFlinger::removeClient_l(pid_t pid) { Loading Loading @@ -2308,8 +2395,10 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, output.buffers.clear(); output.inputId = AUDIO_IO_HANDLE_NONE; // TODO b/182392553: refactor or clean up AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource; AttributionSourceState adjAttributionSource; pid_t callingPid = IPCThreadState::self()->getCallingPid(); if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = input.clientInfo.attributionSource; bool updatePid = (adjAttributionSource.pid == -1); const uid_t callingUid = IPCThreadState::self()->getCallingUid(); const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t( Loading @@ -2318,20 +2407,31 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input, ALOGW_IF(currentUid != callingUid, "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, currentUid); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); adjAttributionSource.uid = VALUE_OR_RETURN_STATUS( legacy2aidl_uid_t_int32_t(callingUid)); updatePid = true; } const pid_t callingPid = IPCThreadState::self()->getCallingPid(); const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t( adjAttributionSource.pid)); if (updatePid) { ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, currentPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); } adjAttributionSource = afutils::checkAttributionSourcePackage( adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller( input.clientInfo.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); } // further format checks are performed by createRecordTrack_l() if (!audio_is_valid_format(input.config.format)) { ALOGE("createRecord() invalid format %#x", input.config.format); Loading Loading @@ -4121,20 +4221,31 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request, int idOut = -1; status_t lStatus = NO_ERROR; // TODO b/182392553: refactor or make clearer const uid_t callingUid = IPCThreadState::self()->getCallingUid(); uid_t callingUid = IPCThreadState::self()->getCallingUid(); pid_t currentPid; if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid)); pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid)); currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid)); if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) { const pid_t callingPid = IPCThreadState::self()->getCallingPid(); ALOGW_IF(currentPid != -1 && currentPid != callingPid, "%s uid %d pid %d tried to pass itself off as pid %d", __func__, callingUid, callingPid, currentPid); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid)); adjAttributionSource.pid = VALUE_OR_RETURN_STATUS( legacy2aidl_pid_t_int32_t(callingPid)); currentPid = callingPid; } adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource); } else { auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED( validateAttributionFromContextOrTrustedCaller(request.attributionSource, getPermissionProvider() )); // TODO pass wrapped object around adjAttributionSource = std::move(validatedAttrSource).unwrapInto(); currentPid = adjAttributionSource.pid; } ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p", adjAttributionSource.pid, effectClient.get(), priority, sessionId, io, Loading
services/audioflinger/AudioFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -407,6 +407,8 @@ private: void onHardError(std::set<audio_port_handle_t>& trackPortIds) final EXCLUDES_AudioFlinger_ClientMutex; const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() final; // ---- end of IAfThreadCallback interface /* List available audio ports and their attributes */ Loading
services/audioflinger/IAfThread.h +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,10 @@ #include <optional> namespace com::android::media::permission { class IPermissionProvider; } namespace android { class IAfDirectOutputThread; Loading Loading @@ -122,6 +126,9 @@ public: EXCLUDES_AudioFlinger_ClientMutex = 0; virtual void onHardError(std::set<audio_port_handle_t>& trackPortIds) = 0; virtual const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() = 0; }; class IAfThreadBase : public virtual RefBase { Loading
services/audioflinger/Threads.cpp +20 −2 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ #include <media/nbaio/Pipe.h> #include <media/nbaio/PipeReader.h> #include <media/nbaio/SourceAudioBufferProvider.h> #include <media/ValidatedAttributionSourceState.h> #include <mediautils/BatteryNotifier.h> #include <mediautils/Process.h> #include <mediautils/SchedulingPolicyService.h> Loading Loading @@ -120,6 +121,8 @@ static inline T min(const T& a, const T& b) return a < b ? a : b; } using com::android::media::permission::ValidatedAttributionSourceState; namespace android { using audioflinger::SyncEvent; Loading Loading @@ -10302,8 +10305,23 @@ status_t MmapThread::start(const AudioClient& client, audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE; audio_io_handle_t io = mId; const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage( AttributionSourceState adjAttributionSource; if (!com::android::media::audio::audioserver_permissions()) { adjAttributionSource = afutils::checkAttributionSourcePackage( client.attributionSource); } else { // TODO(b/342475009) validate in oboeservice, and plumb downwards auto validatedRes = ValidatedAttributionSourceState::createFromTrustedUidNoPackage( client.attributionSource, mAfThreadCallback->getPermissionProvider() ); if (!validatedRes.has_value()) { ALOGE("MMAP client package validation fail: %s", validatedRes.error().toString8().c_str()); return aidl_utils::statusTFromBinderStatus(validatedRes.error()); } adjAttributionSource = std::move(validatedRes.value()).unwrapInto(); } const auto localSessionId = mSessionId; auto localAttr = mAttr; Loading