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

Commit 195205b3 authored by Kevin Rocard's avatar Kevin Rocard
Browse files

Audio HAL VTS: Sanitize prepareFor{Writing,Reading} input size



Return an error if framesCount or frameSize are null to avoid a division
by zero when calculating the buffer size.

The message queues are allocated with a buffer size but if two big they will
assert not return an error.
Thus take some margin on the buffer size check.

Note that both function should be refactored as 99% identical.

Test: vts-tradefed run vts --module VtsHalAudioV2_0Target
Test: call/play music/record/video...
Bug: 36311550
Change-Id: I0576e9016ef2e567c8d4e171c6237883d9865db9
Signed-off-by: default avatarKevin Rocard <krocard@google.com>
parent c07df49e
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -334,8 +334,21 @@ Return<void> StreamIn::prepareForReading(uint32_t frameSize,
        return Void();
    }
    std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));
    if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
        ALOGE("Requested buffer is too big, %d*%d can not fit in size_t",

    // Check frameSize and framesCount
    if (frameSize == 0 || framesCount == 0) {
        ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize,
              framesCount);
        sendError(Result::INVALID_ARGUMENTS);
        return Void();
    }
    // A message queue asserts if it can not handle the requested buffer,
    // thus the client has to guess the maximum size it can handle
    // Choose an arbitrary margin for the overhead of a message queue
    size_t metadataOverhead = 100000;
    if (frameSize >
        (std::numeric_limits<size_t>::max() - metadataOverhead) / framesCount) {
        ALOGE("Buffer too big: %u*%u bytes can not fit in a message queue",
              frameSize, framesCount);
        sendError(Result::INVALID_ARGUMENTS);
        return Void();
+15 −4
Original line number Diff line number Diff line
@@ -311,11 +311,22 @@ Return<void> StreamOut::prepareForWriting(uint32_t frameSize,
    }
    std::unique_ptr<CommandMQ> tempCommandMQ(new CommandMQ(1));

    if (frameSize > std::numeric_limits<size_t>::max() / framesCount) {
        ALOGE("Requested buffer is too big, %d*%d can not fit in size_t",
    // Check frameSize and framesCount
    if (frameSize == 0 || framesCount == 0) {
        ALOGE("Null frameSize (%u) or framesCount (%u)", frameSize,
              framesCount);
        sendError(Result::INVALID_ARGUMENTS);
        return Void();
    }
    // A message queue asserts if it can not handle the requested buffer,
    // thus the client has to guess the maximum size it can handle
    size_t metadataOverhead =
        100000;  // Arbitrary margin for the overhead of a message queue
    if (frameSize >
        (std::numeric_limits<size_t>::max() - metadataOverhead) / framesCount) {
        ALOGE("Buffer too big: %u*%u bytes can not fit in a message queue",
              frameSize, framesCount);
        _hidl_cb(Result::INVALID_ARGUMENTS, CommandMQ::Descriptor(),
                 DataMQ::Descriptor(), StatusMQ::Descriptor(), threadInfo);
        sendError(Result::INVALID_ARGUMENTS);
        return Void();
    }
    std::unique_ptr<DataMQ> tempDataMQ(
+12 −0
Original line number Diff line number Diff line
@@ -1038,6 +1038,12 @@ static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize,
    EXPECT_RESULT(invalidArgsOrNotSupported, res);
}

TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) {
    doc::test(
        "Preparing a stream for reading with a 0 sized buffer should fail");
    testPrepareForReading(stream.get(), 0, 0);
}

TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) {
    doc::test(
        "Preparing a stream for reading with a 2^32 sized buffer should fail");
@@ -1105,6 +1111,12 @@ static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize,
    EXPECT_RESULT(invalidArgsOrNotSupported, res);
}

TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) {
    doc::test(
        "Preparing a stream for writing with a 0 sized buffer should fail");
    testPrepareForWriting(stream.get(), 0, 0);
}

TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) {
    doc::test(
        "Preparing a stream for writing with a 2^32 sized buffer should fail");