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

Commit 3a66c4e0 authored by anjunwen's avatar anjunwen Committed by Cherrypicker Worker
Browse files

C2SoftAacEnc: Clear encoder internal buffer during flush

During flush call, in some cases, encoders internal buffer
may not be cleared and that leads to an error returned
from the encoder library. This leads to OOB access of
mRemainder buffer.
To fix this, plugin clears encoders internal buffer during
flush.

Also, in case of error during encode call, consume all the
input bytes to prevent OOB access of mRemainder buffer.

bug: 264226775
Test: atest CtsMediaV2TestCases
Test: atest VtsHalMediaC2V1_0TargetAudioEncTest
(cherry picked from https://partner-android-review.googlesource.com/q/commit:7da97785c567f9405811451c8b05da6a9f316646)
Merged-In: I197781c8490e1de2217a2aa019ac780c7873f6d5
Change-Id: I197781c8490e1de2217a2aa019ac780c7873f6d5
parent af8be3f5
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ public:
        addParameter(
                DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
                .withDefault(new C2StreamChannelCountInfo::input(0u, 1))
                .withFields({C2F(mChannelCount, value).inRange(1, 6)})
                .withFields({C2F(mChannelCount, value).inRange(1, kMaxChannelCount)})
                .withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
                .build());

@@ -198,10 +198,17 @@ void C2SoftAacEnc::onRelease() {
}

c2_status_t C2SoftAacEnc::onFlush_sm() {
    if (mAACEncoder != nullptr) {
        /* encoder's internal input buffer needs to be reset during flush */
        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CONTROL_STATE, AACENC_INIT_ALL)) {
            ALOGE("Failed to reset AAC encoder");
        }
    }
    mSentCodecSpecificData = false;
    mInputSize = 0u;
    mNextFrameTimestampUs.reset();
    mLastFrameEndTimestampUs.reset();
    mRemainderLen = 0;
    return C2_OK;
}

@@ -562,6 +569,11 @@ void C2SoftAacEnc::process(
                inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
                inargs.numInSamples -= outargs.numInSamples;
            }
        } else {
            // In case of error in encode call, discard remaining input bytes.
            inBuffer[0] = nullptr;
            inBufferSize[0] = 0;
            inargs.numInSamples = 0;
        }
        ALOGV("encoderErr = %d mInputSize = %zu "
              "inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
@@ -597,10 +609,19 @@ void C2SoftAacEnc::process(
                           &outBufDesc,
                           &inargs,
                           &outargs);

        // after flush, discard remaining input bytes.
        inBuffer[0] = nullptr;
        inBufferSize[0] = 0;
    }

    if (inBufferSize[0] > 0) {
        if (inBufferSize[0] > kRemainderBufSize) {
            ALOGE("Remaining bytes %d greater than remainder buffer size %zu", inBufferSize[0],
                    kRemainderBufSize);
            work->result = C2_CORRUPTED;
            return;
        }
        for (size_t i = 0; i < inBufferSize[0]; ++i) {
            mRemainder[i] = static_cast<uint8_t *>(inBuffer[0])[i];
        }
+4 −1
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ public:
            const std::shared_ptr<C2BlockPool> &pool) override;

private:
    static constexpr size_t kMaxChannelCount = 6;
    static constexpr size_t kRemainderBufSize = kMaxChannelCount * sizeof(int16_t);

    std::shared_ptr<IntfImpl> mIntf;

    HANDLE_AACENCODER mAACEncoder;
@@ -63,7 +66,7 @@ private:
    std::atomic_uint64_t mOutIndex;

    // We support max 6 channels
    uint8_t mRemainder[6 * sizeof(int16_t)];
    uint8_t mRemainder[kRemainderBufSize];
    size_t mRemainderLen;

    status_t initEncoder();