AudioPolicy : Add null pointer checks in AudioOutputDescriptor
Since profile is expected to be null for duplicate descriptors,
added null checks for all the usages of the profile
Bug: 306871374
Test: ./audiopolicy_fuzzer clusterfuzz-testcase-minimized-audiopolicy_fuzzer-5131786691608576
Change-Id: I9d40eef2624529ac1b514a176b2a2ca0535f9298
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 4877166..475059c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -322,7 +322,7 @@
mOutput1(0), mOutput2(0), mDirectOpenCount(0),
mDirectClientSession(AUDIO_SESSION_NONE)
{
- if (profile != NULL) {
+ if (profile != nullptr) {
// By default, opening the output without immutable flags, the bit-perfect flags should be
// applied when the apps explicitly request.
mFlags = (audio_output_flags_t)(profile->getFlags() & (~AUDIO_OUTPUT_FLAG_BIT_PERFECT));
@@ -376,7 +376,10 @@
supportedDevices.merge(mOutput2->supportedDevices());
return supportedDevices;
}
- return mProfile->getSupportedDevices();
+ if (mProfile != nullptr) {
+ return mProfile->getSupportedDevices();
+ }
+ return DeviceVector();
}
bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
@@ -407,9 +410,10 @@
if (isDuplicated()) {
return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
|| mOutput2->devicesSupportEncodedFormats(deviceTypes));
- } else {
+ } else if (mProfile != nullptr) {
return mProfile->devicesSupportEncodedFormats(deviceTypes);
}
+ return false;
}
bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
@@ -419,7 +423,10 @@
return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
}
- return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
+ if (mProfile != nullptr) {
+ return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
+ }
+ return false;
}
uint32_t SwAudioOutputDescriptor::latency()
@@ -578,6 +585,11 @@
"with the requested devices, all device types: %s",
__func__, dumpDeviceTypes(devices.types()).c_str());
+ if (mProfile == nullptr) {
+ ALOGE("%s : Cannot open descriptor without a profile ", __func__);
+ return INVALID_OPERATION;
+ }
+
audio_config_t lHalConfig;
if (halConfig == nullptr) {
lHalConfig = AUDIO_CONFIG_INITIALIZER;
@@ -662,7 +674,7 @@
}
return NO_ERROR;
}
- if (!isActive()) {
+ if (mProfile != nullptr && !isActive()) {
if (!mProfile->canStartNewIo()) {
return INVALID_OPERATION;
}
@@ -679,7 +691,7 @@
return;
}
- if (!isActive()) {
+ if (mProfile != nullptr && !isActive()) {
LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
"%s invalid profile active count %u",
__func__, mProfile->curActiveCount);
@@ -702,10 +714,11 @@
}
mClientInterface->closeOutput(mIoHandle);
-
- LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
- __FUNCTION__, mProfile->curOpenCount);
- mProfile->curOpenCount--;
+ if (mProfile != nullptr) {
+ LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
+ __FUNCTION__, mProfile->curOpenCount);
+ mProfile->curOpenCount--;
+ }
mIoHandle = AUDIO_IO_HANDLE_NONE;
}
}
@@ -740,7 +753,10 @@
return std::max(mOutput1->getRecommendedMuteDurationMs(),
mOutput2->getRecommendedMuteDurationMs());
}
- return mProfile->recommendedMuteDurationMs;
+ if (mProfile != nullptr) {
+ return mProfile->recommendedMuteDurationMs;
+ }
+ return 0;
}
void SwAudioOutputDescriptor::setTracksInvalidatedStatusByStrategy(product_strategy_t strategy) {