AudioFlinger: Fix getInputBufferSize() corruption
The uninitialized audio_config_t has a .frame_count which is typically
not used by HALs for this calculation. However, in the case where the
HAL does use this, it can be any 32-bit value.
At best the HAL treats this as invalid or ignores it, but at worst the HAL
casts to uint32_t and causes the caller to request a ridiculous amount of
memory, leading to the process being killed with SIGABRT.
Fix: 146119742
Bug: 144245613
Bug: 144245318
Bug: 144000030
Test: atest AudioRecord_BufferSizeTest
Change-Id: I41714cb2058a6fe7a6a9f55b1fd7c8d862d69351
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d415377..0f756bb 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1582,11 +1582,6 @@
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
- audio_config_t config, proposed;
- memset(&proposed, 0, sizeof(proposed));
- proposed.sample_rate = sampleRate;
- proposed.channel_mask = channelMask;
- proposed.format = format;
sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
std::vector<audio_channel_mask_t> channelMasks = {channelMask};
@@ -1610,12 +1605,16 @@
mHardwareStatus = AUDIO_HW_IDLE;
+ // Change parameters of the configuration each iteration until we find a
+ // configuration that the device will support.
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
for (auto testChannelMask : channelMasks) {
config.channel_mask = testChannelMask;
for (auto testFormat : formats) {
config.format = testFormat;
for (auto testSampleRate : sampleRates) {
config.sample_rate = testSampleRate;
+
size_t bytes = 0;
status_t result = dev->getInputBufferSize(&config, &bytes);
if (result != OK || bytes == 0) {