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

Commit 542ba02f authored by Sohail Nagaraj's avatar Sohail Nagaraj
Browse files

Restrict negative and integer overflow timestamps in the WebmFrameThread

Validating the timestamps before writing to webm writer

Test: ./webm_writer_fuzzer

Bug: 190889324

Change-Id: I1cdf575a3f7115b8c0c816b0a48ac763aab24573
parent d6fd8eee
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -208,6 +208,9 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde
        ALOGE("WriteSampleData() get an NULL buffer.");
        return -EINVAL;
    }
    if (!mWriter->isSampleMetadataValid(trackIndex, timeUs)) {
        return -EINVAL;
    }
    {
        /* As MediaMuxer's writeSampleData handles inputs from multiple tracks,
         * limited the scope of mMuxerLock to this inner block so that the
+6 −0
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ struct MediaWriter : public RefBase {
        return true;
    }

    // Returns true if the sample data is valid.
    virtual bool isSampleMetadataValid([[maybe_unused]] size_t trackIndex,
                                       [[maybe_unused]] int64_t timeUs) {
        return true;
    }

    virtual status_t addSource(const sp<MediaSource> &source) = 0;
    virtual bool reachedEOS() = 0;
    virtual status_t start(MetaData *params = NULL) = 0;
+19 −0
Original line number Diff line number Diff line
@@ -67,6 +67,25 @@ bool WebmWriter::isFdOpenModeValid(int fd) {
    return true;
}

bool WebmWriter::isSampleMetadataValid(size_t trackIndex, int64_t timeUs) {
    int64_t prevTimeUs = 0;
    if (mLastTimestampUsByTrackIndex.find(trackIndex) != mLastTimestampUsByTrackIndex.end()) {
        prevTimeUs = mLastTimestampUsByTrackIndex[trackIndex];
    }
    // WebM has monotonically increasing timestamps
    if (timeUs < 0 || timeUs < prevTimeUs) {
        return false;
    }
    int64_t lastDurationUs = timeUs - prevTimeUs;
    // Ensure that the timeUs value does not overflow,
    // when adding lastDurationUs in the WebmFrameMediaSourceThread.
    if (timeUs > (INT64_MAX / 1000) - lastDurationUs) {
        return false;
    }
    mLastTimestampUsByTrackIndex[trackIndex] = timeUs;
    return true;
}

WebmWriter::WebmWriter(int fd)
    : mFd(dup(fd)),
      mInitCheck(mFd < 0 ? NO_INIT : OK),
+4 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ public:
    // which is compatible with WebmWriter.
    // Note that this overloads that method in the base class.
    static bool isFdOpenModeValid(int fd);
    // Returns true if the timestamp is valid which is compatible with the WebmWriter.
    // Note that this overloads that method in the base class.
    bool isSampleMetadataValid(size_t trackIndex, int64_t timeUs);
    explicit WebmWriter(int fd);
    ~WebmWriter() { reset(); }

@@ -67,6 +70,7 @@ private:
    uint64_t mInfoSize;
    uint64_t mTracksOffset;
    uint64_t mCuesOffset;
    std::map<size_t, int64_t> mLastTimestampUsByTrackIndex;

    bool mPaused;
    bool mStarted;
+3 −0
Original line number Diff line number Diff line
@@ -209,6 +209,9 @@ void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> &currentTrack, int32
    }
    vector<FrameData> bufferInfo = mBufferSource->getFrameList(trackIndex);
    for (int idx = startFrameIndex; idx < endFrameIndex; ++idx) {
        if (!mWriter->isSampleMetadataValid(trackIndex, bufferInfo[idx].timeUs)) {
            continue;
        }
        sp<ABuffer> buffer = new ABuffer((void *)bufferInfo[idx].buf, bufferInfo[idx].size);
        MediaBuffer *mediaBuffer = new MediaBuffer(buffer);