fix crash issue for invalid file
authorhj kim <backto.kim@samsung.com>
Fri, 6 Nov 2020 03:18:43 +0000 (12:18 +0900)
committerbackto.kim <backto.kim@samsung.com>
Mon, 6 Dec 2021 06:49:12 +0000 (15:49 +0900)
Change-Id: Ia95ae3acc672e5a03840e742e8dc6be447b7fb27

libavformat/matroskadec.c

index fb1849f..ac86794 100644 (file)
                                          * to this many bytes of unknown data for the
                                          * SKIP_THRESHOLD check. */
 
+#ifdef __TIZEN__
+#define LIMIT_ATTACHMENT_MEMORY_USE
+#define ATTACHMENT_MEMORY_MAX (5 * 1024 * 1024)
+#define FIX_CRASH_ISSUE_FOR_INVALID_FILE
+#endif
+
 typedef enum {
     EBML_NONE,
     EBML_UINT,
@@ -407,6 +413,9 @@ typedef struct MatroskaDemuxContext {
 
     /* Bandwidth value for WebM DASH Manifest */
     int bandwidth;
+#ifdef FIX_CRASH_ISSUE_FOR_INVALID_FILE
+    int is_parse_header_finish;
+#endif
 } MatroskaDemuxContext;
 
 #define CHILD_OF(parent) { .def = { .n = parent } }
@@ -1310,6 +1319,13 @@ static int ebml_parse(MatroskaDemuxContext *matroska,
         if ((res = ebml_read_length(matroska, pb, &length)) < 0)
             return res;
 
+#ifdef FIX_CRASH_ISSUE_FOR_INVALID_FILE
+        if((length == 0xffffffffffffffULL) && (matroska->is_parse_header_finish == 0)) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "WE DETECTED THIS CONTENT IS A TORRENT FILE!!!\n");
+            return AVERROR_INVALIDDATA;
+        }
+#endif
+
         pos_alt += res;
 
         if (matroska->num_levels > 0) {
@@ -1440,6 +1456,26 @@ static int ebml_parse(MatroskaDemuxContext *matroska,
         res = ebml_read_ascii(pb, length, syntax->def.s, data);
         break;
     case EBML_BIN:
+        #ifdef LIMIT_ATTACHMENT_MEMORY_USE
+        /* some mkv test file has huge attachment data, see defect: W0000246647,
+        this file attchment use more than 46M memory, so in some platform, for
+        example: NVT platform, its memroy is small, this situtation will cause
+        system crash, and currently, Uniplayer does not use attchment data,
+        attchment data is some metadata of matroska, so add this patch to avoid
+        this kind issue.
+        */
+        if(id == MATROSKA_ID_FILEDATA) {
+            if(length > ATTACHMENT_MEMORY_MAX) {
+                    EbmlBin *file_data = (EbmlBin*)data;
+                    file_data->size = 0;
+                    file_data->data = NULL;
+                    file_data->pos = avio_tell(pb);
+                    avio_skip(pb, length);
+                    res = 0;
+                    break;
+            }
+        }
+        #endif
         res = ebml_read_binary(pb, length, pos_alt, data);
         break;
     case EBML_LEVEL1:
@@ -2918,6 +2954,10 @@ static int matroska_read_header(AVFormatContext *s)
     matroska->ctx = s;
     matroska->cues_parsing_deferred = 1;
 
+#ifdef FIX_CRASH_ISSUE_FOR_INVALID_FILE
+    matroska->is_parse_header_finish = 0;
+#endif
+
     /* First read the EBML header. */
     if (ebml_parse(matroska, ebml_syntax, &ebml) || !ebml.doctype) {
         av_log(matroska->ctx, AV_LOG_ERROR, "EBML header parsing failed\n");
@@ -2958,6 +2998,15 @@ static int matroska_read_header(AVFormatContext *s)
     /* The next thing is a segment. */
     pos = avio_tell(matroska->ctx->pb);
     res = ebml_parse(matroska, matroska_segments, matroska);
+
+#ifdef FIX_CRASH_ISSUE_FOR_INVALID_FILE
+    if (res < 0) {
+        av_log(matroska->ctx, AV_LOG_ERROR, "TORRENT FILE, WE QUIT!!!\n");
+        ebml_free(matroska_segments, matroska);
+        return AVERROR_INVALIDDATA;
+    }
+#endif
+
     // Try resyncing until we find an EBML_STOP type element.
     while (res != 1) {
         res = matroska_resync(matroska, pos);
@@ -2968,6 +3017,10 @@ static int matroska_read_header(AVFormatContext *s)
         if (res == AVERROR(EIO)) // EOF is translated to EIO, this exists the loop on EOF
             goto fail;
     }
+#ifdef FIX_CRASH_ISSUE_FOR_INVALID_FILE
+    matroska->is_parse_header_finish = 1;
+#endif
+
     /* Set data_offset as it might be needed later by seek_frame_generic. */
     if (matroska->current_id == MATROSKA_ID_CLUSTER)
         s->internal->data_offset = avio_tell(matroska->ctx->pb) - 4;