summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2024-02-14 09:59:39 -0800
committerLinux Build Service Account <lnxbuild@localhost>2024-02-14 09:59:39 -0800
commitcacbfef31d2a5fbdb946730dfb4267b074736f56 (patch)
tree4b99c87efefb28d6e952524d62dc920f7f271dc1
parent5a9b1de19ae7fa90fc55258f1f568e8c5ddaf8fb (diff)
parent317df0c522ecb4dad7964c3970505f91957f4c52 (diff)
Merge 317df0c522ecb4dad7964c3970505f91957f4c52 on remote branch
Change-Id: I3ec3942a1db70ac8f768711c47b6413e8a134e6c
-rw-r--r--media/audioaidlconversion/AidlConversionCppNdk.cpp20
-rw-r--r--media/libaudioclient/tests/audio_aidl_legacy_conversion_tests.cpp20
-rw-r--r--media/libstagefright/HevcUtils.cpp1
-rw-r--r--media/mtp/MtpPacket.cpp4
-rw-r--r--media/utils/ServiceUtilities.cpp43
-rw-r--r--media/utils/include/mediautils/ServiceUtilities.h4
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp46
7 files changed, 135 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/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 60df1628ae..1653bcdb7b 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -78,6 +78,7 @@ status_t HevcParameterSets::addNalUnit(const uint8_t* data, size_t size) {
}
err = parsePps(data + 2, size - 2);
break;
+ case 35: // AUD
case 39: // Prefix SEI
case 40: // Suffix SEI
// Ignore
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)));