Loading media/utils/ServiceUtilities.cpp +23 −14 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include "mediautils/ServiceUtilities.h" #include <system/audio-hal-enums.h> #include <iterator> #include <algorithm> Loading Loading @@ -61,8 +62,20 @@ static String16 resolveCallingPackage(PermissionController& permissionController return packages[0]; } static int32_t getOpForSource(audio_source_t source) { switch (source) { case AUDIO_SOURCE_HOTWORD: return AppOpsManager::OP_RECORD_AUDIO_HOTWORD; case AUDIO_SOURCE_REMOTE_SUBMIX: return AppOpsManager::OP_RECORD_AUDIO_OUTPUT; case AUDIO_SOURCE_DEFAULT: default: return AppOpsManager::OP_RECORD_AUDIO; } } static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, uid_t uid, bool start, bool isHotwordSource) { uid_t uid, bool start, audio_source_t source) { // Okay to not track in app ops as audio server or media server is us and if // device is rooted security model is considered compromised. // system_server loses its RECORD_AUDIO permission when a secondary Loading @@ -87,11 +100,8 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } AppOpsManager appOps; const int32_t opRecordAudio = appOps.permissionToOpCode(sAndroidPermissionRecordAudio); const int32_t op = getOpForSource(source); if (start) { const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD : opRecordAudio; if (int32_t mode = appOps.startOpNoThrow( op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false); mode != AppOpsManager::MODE_ALLOWED) { Loading @@ -101,10 +111,10 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } } else { // Always use OP_RECORD_AUDIO for checks at creation time. if (int32_t mode = appOps.checkOp(opRecordAudio, uid, resolvedOpPackageName); if (int32_t mode = appOps.checkOp(op, uid, resolvedOpPackageName); mode != AppOpsManager::MODE_ALLOWED) { ALOGE("Request check for \"%s\" (uid %d) denied by app op: %d, mode: %d", String8(resolvedOpPackageName).c_str(), uid, opRecordAudio, mode); String8(resolvedOpPackageName).c_str(), uid, op, mode); return false; } } Loading @@ -113,15 +123,14 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, /*is_hotword_source*/ false); return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, AUDIO_SOURCE_DEFAULT); } bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, isHotwordSource); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, source); } void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource) { void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source) { // Okay to not track in app ops as audio server is us and if // device is rooted security model is considered compromised. if (isAudioServerOrRootUid(uid)) return; Loading @@ -134,8 +143,8 @@ void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSou } AppOpsManager appOps; const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD : appOps.permissionToOpCode(sAndroidPermissionRecordAudio); const int32_t op = getOpForSource(source); appOps.finishOp(op, uid, resolvedOpPackageName); } Loading media/utils/fuzzers/ServiceUtilitiesFuzz.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <fcntl.h> #include <functional> #include <type_traits> #include "fuzzer/FuzzedDataProvider.h" #include "mediautils/ServiceUtilities.h" Loading Loading @@ -44,7 +45,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider data_provider(data, size); uid_t uid = data_provider.ConsumeIntegral<uid_t>(); pid_t pid = data_provider.ConsumeIntegral<pid_t>(); bool isHotword = data_provider.ConsumeBool(); audio_source_t source = static_cast<audio_source_t>(data_provider .ConsumeIntegral<std::underlying_type_t<audio_source_t>>()); // There is not state here, and order is not significant, // so we can simply call all of the target functions Loading @@ -55,8 +57,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen); android::String16 opPackageName(packageNameStr.c_str()); android::recordingAllowed(opPackageName, pid, uid); android::startRecording(opPackageName, pid, uid, isHotword); android::finishRecording(opPackageName, uid, isHotword); android::startRecording(opPackageName, pid, uid, source); android::finishRecording(opPackageName, uid, source); android::captureAudioOutputAllowed(pid, uid); android::captureMediaOutputAllowed(pid, uid); android::captureHotwordAllowed(opPackageName, pid, uid); Loading media/utils/include/mediautils/ServiceUtilities.h +3 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <binder/PermissionController.h> #include <cutils/multiuser.h> #include <private/android_filesystem_config.h> #include <system/audio-hal-enums.h> #include <map> #include <optional> Loading Loading @@ -79,8 +80,8 @@ static inline bool isAudioServerOrMediaServerUid(uid_t uid) { } bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource); void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source); void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source); bool captureAudioOutputAllowed(pid_t pid, uid_t uid); bool captureMediaOutputAllowed(pid_t pid, uid_t uid); bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid); Loading services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -574,7 +574,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId) // check calling permissions if (!(startRecording(client->opPackageName, client->pid, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD) client->attributes.source) || client->attributes.source == AUDIO_SOURCE_FM_TUNER)) { ALOGE("%s permission denied: recording not allowed for uid %d pid %d", __func__, client->uid, client->pid); Loading Loading @@ -663,7 +663,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId) client->startTimeNs = 0; updateUidStates_l(); finishRecording(client->opPackageName, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD); client->attributes.source); } return status; Loading @@ -690,7 +690,7 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId) // finish the recording app op finishRecording(client->opPackageName, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD); client->attributes.source); AutoCallerClear acc; return mAudioPolicyManager->stopInput(portId); } Loading Loading
media/utils/ServiceUtilities.cpp +23 −14 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> #include "mediautils/ServiceUtilities.h" #include <system/audio-hal-enums.h> #include <iterator> #include <algorithm> Loading Loading @@ -61,8 +62,20 @@ static String16 resolveCallingPackage(PermissionController& permissionController return packages[0]; } static int32_t getOpForSource(audio_source_t source) { switch (source) { case AUDIO_SOURCE_HOTWORD: return AppOpsManager::OP_RECORD_AUDIO_HOTWORD; case AUDIO_SOURCE_REMOTE_SUBMIX: return AppOpsManager::OP_RECORD_AUDIO_OUTPUT; case AUDIO_SOURCE_DEFAULT: default: return AppOpsManager::OP_RECORD_AUDIO; } } static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, uid_t uid, bool start, bool isHotwordSource) { uid_t uid, bool start, audio_source_t source) { // Okay to not track in app ops as audio server or media server is us and if // device is rooted security model is considered compromised. // system_server loses its RECORD_AUDIO permission when a secondary Loading @@ -87,11 +100,8 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } AppOpsManager appOps; const int32_t opRecordAudio = appOps.permissionToOpCode(sAndroidPermissionRecordAudio); const int32_t op = getOpForSource(source); if (start) { const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD : opRecordAudio; if (int32_t mode = appOps.startOpNoThrow( op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false); mode != AppOpsManager::MODE_ALLOWED) { Loading @@ -101,10 +111,10 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } } else { // Always use OP_RECORD_AUDIO for checks at creation time. if (int32_t mode = appOps.checkOp(opRecordAudio, uid, resolvedOpPackageName); if (int32_t mode = appOps.checkOp(op, uid, resolvedOpPackageName); mode != AppOpsManager::MODE_ALLOWED) { ALOGE("Request check for \"%s\" (uid %d) denied by app op: %d, mode: %d", String8(resolvedOpPackageName).c_str(), uid, opRecordAudio, mode); String8(resolvedOpPackageName).c_str(), uid, op, mode); return false; } } Loading @@ -113,15 +123,14 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid, } bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, /*is_hotword_source*/ false); return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false, AUDIO_SOURCE_DEFAULT); } bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, isHotwordSource); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source) { return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, source); } void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource) { void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source) { // Okay to not track in app ops as audio server is us and if // device is rooted security model is considered compromised. if (isAudioServerOrRootUid(uid)) return; Loading @@ -134,8 +143,8 @@ void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSou } AppOpsManager appOps; const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD : appOps.permissionToOpCode(sAndroidPermissionRecordAudio); const int32_t op = getOpForSource(source); appOps.finishOp(op, uid, resolvedOpPackageName); } Loading
media/utils/fuzzers/ServiceUtilitiesFuzz.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <fcntl.h> #include <functional> #include <type_traits> #include "fuzzer/FuzzedDataProvider.h" #include "mediautils/ServiceUtilities.h" Loading Loading @@ -44,7 +45,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider data_provider(data, size); uid_t uid = data_provider.ConsumeIntegral<uid_t>(); pid_t pid = data_provider.ConsumeIntegral<pid_t>(); bool isHotword = data_provider.ConsumeBool(); audio_source_t source = static_cast<audio_source_t>(data_provider .ConsumeIntegral<std::underlying_type_t<audio_source_t>>()); // There is not state here, and order is not significant, // so we can simply call all of the target functions Loading @@ -55,8 +57,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen); android::String16 opPackageName(packageNameStr.c_str()); android::recordingAllowed(opPackageName, pid, uid); android::startRecording(opPackageName, pid, uid, isHotword); android::finishRecording(opPackageName, uid, isHotword); android::startRecording(opPackageName, pid, uid, source); android::finishRecording(opPackageName, uid, source); android::captureAudioOutputAllowed(pid, uid); android::captureMediaOutputAllowed(pid, uid); android::captureHotwordAllowed(opPackageName, pid, uid); Loading
media/utils/include/mediautils/ServiceUtilities.h +3 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <binder/PermissionController.h> #include <cutils/multiuser.h> #include <private/android_filesystem_config.h> #include <system/audio-hal-enums.h> #include <map> #include <optional> Loading Loading @@ -79,8 +80,8 @@ static inline bool isAudioServerOrMediaServerUid(uid_t uid) { } bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource); void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource); bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, audio_source_t source); void finishRecording(const String16& opPackageName, uid_t uid, audio_source_t source); bool captureAudioOutputAllowed(pid_t pid, uid_t uid); bool captureMediaOutputAllowed(pid_t pid, uid_t uid); bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid); Loading
services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -574,7 +574,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId) // check calling permissions if (!(startRecording(client->opPackageName, client->pid, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD) client->attributes.source) || client->attributes.source == AUDIO_SOURCE_FM_TUNER)) { ALOGE("%s permission denied: recording not allowed for uid %d pid %d", __func__, client->uid, client->pid); Loading Loading @@ -663,7 +663,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId) client->startTimeNs = 0; updateUidStates_l(); finishRecording(client->opPackageName, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD); client->attributes.source); } return status; Loading @@ -690,7 +690,7 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId) // finish the recording app op finishRecording(client->opPackageName, client->uid, client->attributes.source == AUDIO_SOURCE_HOTWORD); client->attributes.source); AutoCallerClear acc; return mAudioPolicyManager->stopInput(portId); } Loading