Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9899ff7f authored by Robin Lee's avatar Robin Lee
Browse files

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
parent b7b2f5d8
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -1582,11 +1582,6 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form

    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 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form

    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) {