diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-30 11:14:28 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-30 11:14:28 +0000 |
commit | 317df0c522ecb4dad7964c3970505f91957f4c52 (patch) | |
tree | 4b99c87efefb28d6e952524d62dc920f7f271dc1 | |
parent | 6c0e19f33a2d8cad0bd432711c890fc85ca4b42e (diff) | |
parent | 200cc8eb73bdd5f5177d4f7d11daccb9ddea6a85 (diff) |
Snap for 11376178 from 200cc8eb73bdd5f5177d4f7d11daccb9ddea6a85 to u-keystone-qcom-release
Change-Id: I4d1d24eb690d4d9fa4a0c3dea0b5c2c47b5c48c5
-rw-r--r-- | media/audioaidlconversion/AidlConversionCppNdk.cpp | 20 | ||||
-rw-r--r-- | media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp | 20 | ||||
-rw-r--r-- | media/mtp/MtpPacket.cpp | 4 | ||||
-rw-r--r-- | media/utils/ServiceUtilities.cpp | 43 | ||||
-rw-r--r-- | media/utils/include/mediautils/ServiceUtilities.h | 4 | ||||
-rw-r--r-- | services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp | 46 |
6 files changed, 134 insertions, 3 deletions
diff --git a/media/audioaidlconversion/AidlConversionCppNdk.cpp b/media/audioaidlconversion/AidlConversionCppNdk.cpp index 3b06245e0b..f13cfa3aab 100644 --- a/media/audioaidlconversion/AidlConversionCppNdk.cpp +++ b/media/audioaidlconversion/AidlConversionCppNdk.cpp @@ -1052,6 +1052,13 @@ AudioDeviceAddress::Tag suggestDeviceAddressTag(const AudioDeviceDescription& de if (mac.size() != 6) return BAD_VALUE; snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + // special case for anonymized mac address: + // change anonymized bytes back from FD:FF:FF:FF to XX:XX:XX:XX + std::string address(addressBuffer); + if (address.compare(0, strlen("FD:FF:FF:FF"), "FD:FF:FF:FF") == 0) { + address.replace(0, strlen("FD:FF:FF:FF"), "XX:XX:XX:XX"); + } + strcpy(addressBuffer, address.c_str()); } break; case Tag::ipv4: { const std::vector<uint8_t>& ipv4 = aidl.address.get<AudioDeviceAddress::ipv4>(); @@ -1108,11 +1115,20 @@ legacy2aidl_audio_device_AudioDevice( if (!legacyAddress.empty()) { switch (suggestDeviceAddressTag(aidl.type)) { case Tag::mac: { + // special case for anonymized mac address: + // change anonymized bytes so that they can be scanned as HEX bytes + // Use '01' for LSB bits 0 and 1 as Bluetooth MAC addresses are never multicast + // and universaly administered + std::string address = legacyAddress; + if (address.compare(0, strlen("XX:XX:XX:XX"), "XX:XX:XX:XX") == 0) { + address.replace(0, strlen("XX:XX:XX:XX"), "FD:FF:FF:FF"); + } + std::vector<uint8_t> mac(6); - int status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", + int status = sscanf(address.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); if (status != mac.size()) { - ALOGE("%s: malformed MAC address: \"%s\"", __func__, legacyAddress.c_str()); + ALOGE("%s: malformed MAC address: \"%s\"", __func__, address.c_str()); return unexpected(BAD_VALUE); } aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::mac>(std::move(mac)); diff --git a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp index 0d12f9d9e1..67473cec5e 100644 --- a/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp +++ b/media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp @@ -475,8 +475,28 @@ INSTANTIATE_TEST_SUITE_P( AudioDeviceAddress::make<AudioDeviceAddress::Tag::alsa>( std::vector<int32_t>{1, 2})))); +TEST(AnonymizedBluetoothAddressRoundTripTest, Legacy2Aidl2Legacy) { + const std::vector<uint8_t> sAnonymizedAidlAddress = + std::vector<uint8_t>{0xFD, 0xFF, 0xFF, 0xFF, 0xAB, 0xCD}; + const std::string sAnonymizedLegacyAddress = std::string("XX:XX:XX:XX:AB:CD"); + auto device = legacy2aidl_audio_device_AudioDevice(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, + sAnonymizedLegacyAddress); + ASSERT_TRUE(device.ok()); + ASSERT_EQ(AudioDeviceAddress::Tag::mac, device.value().address.getTag()); + ASSERT_EQ(sAnonymizedAidlAddress, device.value().address.get<AudioDeviceAddress::mac>()); + + audio_devices_t legacyType; + std::string legacyAddress; + status_t status = + aidl2legacy_AudioDevice_audio_device(device.value(), &legacyType, &legacyAddress); + ASSERT_EQ(OK, status); + EXPECT_EQ(legacyType, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP); + EXPECT_EQ(sAnonymizedLegacyAddress, legacyAddress); +} + class AudioFormatDescriptionRoundTripTest : public testing::TestWithParam<AudioFormatDescription> { }; + TEST_P(AudioFormatDescriptionRoundTripTest, Aidl2Legacy2Aidl) { const auto initial = GetParam(); auto conv = aidl2legacy_AudioFormatDescription_audio_format_t(initial); diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp index 5faaac2026..634aa46dd9 100644 --- a/media/mtp/MtpPacket.cpp +++ b/media/mtp/MtpPacket.cpp @@ -168,8 +168,10 @@ void MtpPacket::setParameter(int index, uint32_t value) { return; } int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); - if (mPacketSize < offset + sizeof(uint32_t)) + if (mPacketSize < offset + sizeof(uint32_t)) { mPacketSize = offset + sizeof(uint32_t); + allocate(mPacketSize); + } putUInt32(offset, value); } diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp index 83b84e392c..4ee45c795e 100644 --- a/media/utils/ServiceUtilities.cpp +++ b/media/utils/ServiceUtilities.cpp @@ -46,6 +46,7 @@ static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_A 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 sAndroidPermissionBluetoothConnect("android.permission.BLUETOOTH_CONNECT"); static String16 resolveCallingPackage(PermissionController& permissionController, const std::optional<String16> opPackageName, uid_t uid) { @@ -374,6 +375,48 @@ status_t checkIMemory(const sp<IMemory>& iMemory) return NO_ERROR; } +/** + * Determines if the MAC address in Bluetooth device descriptors returned by APIs of + * a native audio service (audio flinger, audio policy) must be anonymized. + * MAC addresses returned to system server or apps with BLUETOOTH_CONNECT permission + * are not anonymized. + * + * @param attributionSource The attribution source of the calling app. + * @param caller string identifying the caller for logging. + * @return true if the MAC addresses must be anonymized, false otherwise. + */ +bool mustAnonymizeBluetoothAddress( + const AttributionSourceState& attributionSource, const String16& caller) { + uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid)); + if (isAudioServerOrSystemServerUid(uid)) { + return false; + } + const std::optional<AttributionSourceState> resolvedAttributionSource = + resolveAttributionSource(attributionSource); + if (!resolvedAttributionSource.has_value()) { + return true; + } + permission::PermissionChecker permissionChecker; + return permissionChecker.checkPermissionForPreflightFromDatasource( + sAndroidPermissionBluetoothConnect, resolvedAttributionSource.value(), caller, + AppOpsManager::OP_BLUETOOTH_CONNECT) + != permission::PermissionChecker::PERMISSION_GRANTED; +} + +/** + * Modifies the passed MAC address string in place for consumption by unprivileged clients. + * the string is assumed to have a valid MAC address format. + * the anonymzation must be kept in sync with toAnonymizedAddress() in BluetoothUtils.java + * + * @param address input/output the char string contining the MAC address to anonymize. + */ +void anonymizeBluetoothAddress(char *address) { + if (address == nullptr || strlen(address) != strlen("AA:BB:CC:DD:EE:FF")) { + return; + } + memcpy(address, "XX:XX:XX:XX", strlen("XX:XX:XX:XX")); +} + sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() { const sp<IServiceManager> sm = defaultServiceManager(); if (sm == nullptr) { diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h index 3d7981ae97..0b3a3f96cd 100644 --- a/media/utils/include/mediautils/ServiceUtilities.h +++ b/media/utils/include/mediautils/ServiceUtilities.h @@ -108,6 +108,10 @@ bool modifyPhoneStateAllowed(const AttributionSourceState& attributionSource); bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource); bool callAudioInterceptionAllowed(const AttributionSourceState& attributionSource); void purgePermissionCache(); +bool mustAnonymizeBluetoothAddress( + const AttributionSourceState& attributionSource, const String16& caller); +void anonymizeBluetoothAddress(char *address); + int32_t getOpForSource(audio_source_t source); AttributionSourceState getCallingAttributionSource(); diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp index 062133343b..c3c218ff58 100644 --- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp @@ -1548,6 +1548,19 @@ Status AudioPolicyService::isDirectOutputSupported( return Status::ok(); } +template <typename Port> +void anonymizePortBluetoothAddress(Port *port) { + if (port->type != AUDIO_PORT_TYPE_DEVICE) { + return; + } + if (!(audio_is_a2dp_device(port->ext.device.type) + || audio_is_ble_device(port->ext.device.type) + || audio_is_bluetooth_sco_device(port->ext.device.type) + || audio_is_hearing_aid_out_device(port->ext.device.type))) { + return; + } + anonymizeBluetoothAddress(port->ext.device.address); +} Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl, media::AudioPortType typeAidl, Int* count, @@ -1570,10 +1583,20 @@ Status AudioPolicyService::listAudioPorts(media::AudioPortRole roleAidl, if (mAudioPolicyManager == NULL) { return binderStatusFromStatusT(NO_INIT); } + + const AttributionSourceState attributionSource = getCallingAttributionSource(); + AutoCallerClear acc; RETURN_IF_BINDER_ERROR(binderStatusFromStatusT( mAudioPolicyManager->listAudioPorts(role, type, &num_ports, ports.get(), &generation))); numPortsReq = std::min(numPortsReq, num_ports); + + if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) { + for (size_t i = 0; i < numPortsReq; ++i) { + anonymizePortBluetoothAddress(&ports[i]); + } + } + RETURN_IF_BINDER_ERROR(binderStatusFromStatusT( convertRange(ports.get(), ports.get() + numPortsReq, std::back_inserter(*portsAidl), legacy2aidl_audio_port_v7_AudioPortFw))); @@ -1600,8 +1623,16 @@ Status AudioPolicyService::getAudioPort(int portId, if (mAudioPolicyManager == NULL) { return binderStatusFromStatusT(NO_INIT); } + + const AttributionSourceState attributionSource = getCallingAttributionSource(); + AutoCallerClear acc; RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(mAudioPolicyManager->getAudioPort(&port))); + + if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) { + anonymizePortBluetoothAddress(&port); + } + *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_audio_port_v7_AudioPortFw(port)); return Status::ok(); } @@ -1663,10 +1694,25 @@ Status AudioPolicyService::listAudioPatches(Int* count, if (mAudioPolicyManager == NULL) { return binderStatusFromStatusT(NO_INIT); } + + const AttributionSourceState attributionSource = getCallingAttributionSource(); + AutoCallerClear acc; RETURN_IF_BINDER_ERROR(binderStatusFromStatusT( mAudioPolicyManager->listAudioPatches(&num_patches, patches.get(), &generation))); numPatchesReq = std::min(numPatchesReq, num_patches); + + if (mustAnonymizeBluetoothAddress(attributionSource, String16(__func__))) { + for (size_t i = 0; i < numPatchesReq; ++i) { + for (size_t j = 0; j < patches[i].num_sources; ++j) { + anonymizePortBluetoothAddress(&patches[i].sources[j]); + } + for (size_t j = 0; j < patches[i].num_sinks; ++j) { + anonymizePortBluetoothAddress(&patches[i].sinks[j]); + } + } + } + RETURN_IF_BINDER_ERROR(binderStatusFromStatusT( convertRange(patches.get(), patches.get() + numPatchesReq, std::back_inserter(*patchesAidl), legacy2aidl_audio_patch_AudioPatchFw))); |