Add permission check for audio attributes tags.
Audio attributes tags are system APIs in NDK that can be used to affect
routing, volume control, etc. In that case, apply
MODIFY_AUDIO_SETTINGS_PRIVILEGED permission check to protect it.
Bug: 378909923
Test: atest test_attributes
Flag: EXEMPT NDK
Change-Id: Id2a4063b72587e9495bd1221ef82122725f28b5a
diff --git a/aidl/com/android/media/permission/PermissionEnum.aidl b/aidl/com/android/media/permission/PermissionEnum.aidl
index 7badb87..8eeae10 100644
--- a/aidl/com/android/media/permission/PermissionEnum.aidl
+++ b/aidl/com/android/media/permission/PermissionEnum.aidl
@@ -38,5 +38,6 @@
CAPTURE_VOICE_COMMUNICATION_OUTPUT = 12,
BLUETOOTH_CONNECT = 13,
BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION = 14,
- ENUM_SIZE = 15, // Not for actual usage, used by Java
+ MODIFY_AUDIO_SETTINGS_PRIVILEGED = 15,
+ ENUM_SIZE = 16, // Not for actual usage, used by Java
}
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 39a172f..8ceff96 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -55,6 +55,8 @@
static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
static const String16 sCallAudioInterception("android.permission.CALL_AUDIO_INTERCEPTION");
+static const String16 sModifyAudioSettingsPrivileged(
+ "android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED");
static String16 resolveCallingPackage(PermissionController& permissionController,
const std::optional<String16> opPackageName, uid_t uid) {
@@ -387,6 +389,17 @@
return ok;
}
+bool modifyAudioSettingsPrivilegedAllowed(const AttributionSourceState& attributionSource) {
+ uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
+ pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
+ if (isAudioServerUid(uid)) return true;
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkPermission(sModifyAudioSettingsPrivileged, pid, uid);
+ if (!ok) ALOGE("%s(): android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED denied for uid %d",
+ __func__, uid);
+ return ok;
+}
+
bool dumpAllowed() {
static const String16 sDump("android.permission.DUMP");
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 573cc14..42789d5 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -110,6 +110,7 @@
bool modifyAudioRoutingAllowed(const AttributionSourceState& attributionSource);
bool modifyDefaultAudioEffectsAllowed();
bool modifyDefaultAudioEffectsAllowed(const AttributionSourceState& attributionSource);
+bool modifyAudioSettingsPrivilegedAllowed(const AttributionSourceState& attributionSource);
bool dumpAllowed();
bool modifyPhoneStateAllowed(const AttributionSourceState& attributionSource);
bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 12320b7..802ebeb 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -73,6 +73,7 @@
using com::android::media::permission::PermissionEnum::CAPTURE_TUNER_AUDIO_INPUT;
using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_ROUTING;
using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_SETTINGS;
+using com::android::media::permission::PermissionEnum::MODIFY_AUDIO_SETTINGS_PRIVILEGED;
using com::android::media::permission::PermissionEnum::MODIFY_DEFAULT_AUDIO_EFFECTS;
using com::android::media::permission::PermissionEnum::MODIFY_PHONE_STATE;
using com::android::media::permission::PermissionEnum::RECORD_AUDIO;
@@ -443,6 +444,16 @@
}
}
+ if (strlen(attr.tags) != 0) {
+ if (!(audioserver_permissions() ?
+ CHECK_PERM(MODIFY_AUDIO_SETTINGS_PRIVILEGED, attributionSource.uid)
+ : modifyAudioSettingsPrivilegedAllowed(attributionSource))) {
+ ALOGE("%s: permission denied: audio attributes tags not allowed for uid %d pid %d",
+ __func__, attributionSource.uid, attributionSource.pid);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
+ }
+ }
+
AutoCallerClear acc;
AudioPolicyInterface::output_type_t outputType;
bool isSpatialized = false;