Merge "Restrict negative and integer overflow timestamps in the WebmFrameThread" into main
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index 9768f97..aaf7465 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -208,6 +208,9 @@
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
diff --git a/media/libstagefright/include/media/stagefright/MediaWriter.h b/media/libstagefright/include/media/stagefright/MediaWriter.h
index 2b14811..04dcfc0 100644
--- a/media/libstagefright/include/media/stagefright/MediaWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaWriter.h
@@ -54,6 +54,12 @@
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;
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index 3823c36..ca862b0 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -67,6 +67,25 @@
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),
diff --git a/media/libstagefright/webm/include/webm/WebmWriter.h b/media/libstagefright/webm/include/webm/WebmWriter.h
index e339add..4c51f0e 100644
--- a/media/libstagefright/webm/include/webm/WebmWriter.h
+++ b/media/libstagefright/webm/include/webm/WebmWriter.h
@@ -40,6 +40,9 @@
// 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 @@
uint64_t mInfoSize;
uint64_t mTracksOffset;
uint64_t mCuesOffset;
+ std::map<size_t, int64_t> mLastTimestampUsByTrackIndex;
bool mPaused;
bool mStarted;
diff --git a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
index fee5c94..7235ba9 100644
--- a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
+++ b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
@@ -209,6 +209,9 @@
}
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);