[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#897368: stretch-pu: package faad2/2.8.0~cvs20161113-1



Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@packages.debian.org
Usertags: pu

Dear release team,

I would like to update faad2 in Stretch and fix all currently open
CVEs. The security team marked them as no-dsa and the maintainer does
not seem to have any interest in fixing them. The patch is almost
identical to the version in Wheezy which has proven to work for a
couple of months now. Please find attached the debdiff.

Regards,

Markus
diff -Nru faad2-2.8.0~cvs20161113/debian/changelog faad2-2.8.0~cvs20161113/debian/changelog
--- faad2-2.8.0~cvs20161113/debian/changelog	2016-11-13 17:45:15.000000000 +0100
+++ faad2-2.8.0~cvs20161113/debian/changelog	2018-05-01 17:49:02.000000000 +0200
@@ -1,3 +1,15 @@
+faad2 (2.8.0~cvs20161113-1+deb9u1) stretch; urgency=high
+
+  * Non-maintainer upload.
+  * Fix CVE-2017-9218, CVE-2017-9219, CVE-2017-9220, CVE-2017-9221,
+    CVE-2017-9222, CVE-2017-9223, CVE-2017-9253, CVE-2017-9254, CVE-2017-9255,
+    CVE-2017-9256, CVE-2017-9257.
+    Various issues were discovered in faad2, a fast audio decoder, that could
+    cause a denial of service (large loop and CPU consumption) via a crafted
+    mp4 file. (Closes: #889915)
+
+ -- Markus Koschany <apo@debian.org>  Tue, 01 May 2018 17:49:02 +0200
+
 faad2 (2.8.0~cvs20161113-1) unstable; urgency=medium
 
   * New upstream CVS snapshot.
diff -Nru faad2-2.8.0~cvs20161113/debian/patches/CVE-2017-92xx.patch faad2-2.8.0~cvs20161113/debian/patches/CVE-2017-92xx.patch
--- faad2-2.8.0~cvs20161113/debian/patches/CVE-2017-92xx.patch	1970-01-01 01:00:00.000000000 +0100
+++ faad2-2.8.0~cvs20161113/debian/patches/CVE-2017-92xx.patch	2018-05-01 17:49:02.000000000 +0200
@@ -0,0 +1,552 @@
+From: Markus Koschany <apo@debian.org>
+Date: Tue, 1 May 2018 17:47:28 +0200
+Subject: CVE-2017-92xx
+
+Bug-Debian: https://bugs.debian.org/867724
+Origin: https://sourceforge.net/p/faac/faad2/ci/a67c75ed600cf4b41205d69664d3d9106e9c5380/
+---
+ common/mp4ff/mp4atom.c  |  76 ++++++++++++++++++++++++++----
+ common/mp4ff/mp4ff.c    |  22 ++++++++-
+ common/mp4ff/mp4ff.h    | 123 +++++++++++++++++++++++++++++++++++++++---------
+ common/mp4ff/mp4ffint.h | 105 +----------------------------------------
+ common/mp4ff/mp4meta.c  |   4 +-
+ common/mp4ff/mp4util.c  |   3 ++
+ 6 files changed, 197 insertions(+), 136 deletions(-)
+
+diff --git a/common/mp4ff/mp4atom.c b/common/mp4ff/mp4atom.c
+index c735c2a..e88ffb4 100644
+--- a/common/mp4ff/mp4atom.c
++++ b/common/mp4ff/mp4atom.c
+@@ -258,6 +258,9 @@ uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_
+ 
+ static int32_t mp4ff_read_stsz(mp4ff_t *f)
+ {
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     mp4ff_read_char(f); /* version */
+     mp4ff_read_int24(f); /* flags */
+     f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
+@@ -269,7 +272,10 @@ static int32_t mp4ff_read_stsz(mp4ff_t *f)
+         f->track[f->total_tracks - 1]->stsz_table =
+             (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
+ 
+-        for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
++        if (!f->track[f->total_tracks - 1]->stsz_table)
++            return f->error++;
++
++        for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count && !f->stream->read_error; i++)
+         {
+             f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
+         }
+@@ -283,6 +289,9 @@ static int32_t mp4ff_read_esds(mp4ff_t *f)
+     uint8_t tag;
+     uint32_t temp;
+ 
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     mp4ff_read_char(f); /* version */
+     mp4ff_read_int24(f); /* flags */
+ 
+@@ -347,6 +356,9 @@ static int32_t mp4ff_read_mp4a(mp4ff_t *f)
+     uint8_t atom_type = 0;
+     uint8_t header_size = 0;
+ 
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     for (i = 0; i < 6; i++)
+     {
+         mp4ff_read_char(f); /* reserved */
+@@ -380,12 +392,16 @@ static int32_t mp4ff_read_stsd(mp4ff_t *f)
+     int32_t i;
+     uint8_t header_size = 0;
+ 
++    /* CVE-2017-9218 */
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     mp4ff_read_char(f); /* version */
+     mp4ff_read_int24(f); /* flags */
+ 
+     f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
+ 
+-    for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
++    for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count && !f->stream->read_error; i++) /* CVE-2017-9253 */
+     {
+         uint64_t skip = mp4ff_position(f);
+         uint64_t size;
+@@ -415,6 +431,9 @@ static int32_t mp4ff_read_stsc(mp4ff_t *f)
+ {
+     int32_t i;
+ 
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     mp4ff_read_char(f); /* version */
+     mp4ff_read_int24(f); /* flags */
+     f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
+@@ -426,7 +445,27 @@ static int32_t mp4ff_read_stsc(mp4ff_t *f)
+     f->track[f->total_tracks - 1]->stsc_sample_desc_index =
+         (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
+ 
+-    for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
++    /* CVE-2017-9219 */
++    if (!f->track[f->total_tracks - 1]->stsc_first_chunk)
++    {
++        return f->error++;
++    }
++    if (!f->track[f->total_tracks - 1]->stsc_samples_per_chunk)
++    {
++        free(f->track[f->total_tracks - 1]->stsc_first_chunk);
++        f->track[f->total_tracks - 1]->stsc_first_chunk = NULL;
++        return f->error++;
++    }
++    if (!f->track[f->total_tracks - 1]->stsc_sample_desc_index)
++    {
++        free(f->track[f->total_tracks - 1]->stsc_first_chunk);
++        f->track[f->total_tracks - 1]->stsc_first_chunk = NULL;
++        free(f->track[f->total_tracks - 1]->stsc_samples_per_chunk);
++        f->track[f->total_tracks - 1]->stsc_samples_per_chunk = NULL;
++        return f->error++;
++    }
++
++    for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count && !f->stream->read_error; i++) /* CVE-2017-9255 */
+     {
+         f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
+         f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
+@@ -440,6 +479,9 @@ static int32_t mp4ff_read_stco(mp4ff_t *f)
+ {
+     int32_t i;
+ 
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     mp4ff_read_char(f); /* version */
+     mp4ff_read_int24(f); /* flags */
+     f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
+@@ -447,7 +489,11 @@ static int32_t mp4ff_read_stco(mp4ff_t *f)
+     f->track[f->total_tracks - 1]->stco_chunk_offset =
+         (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
+ 
+-    for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
++    /* CVE-2017-9220 */
++    if (!f->track[f->total_tracks - 1]->stco_chunk_offset)
++        return f->error++;
++
++    for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count && !f->stream->read_error; i++) /* CVE-2017-9256 */
+     {
+         f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
+     }
+@@ -458,8 +504,12 @@ static int32_t mp4ff_read_stco(mp4ff_t *f)
+ static int32_t mp4ff_read_ctts(mp4ff_t *f)
+ {
+     int32_t i;
+-    mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
++    mp4ff_track_t * p_track;
+ 
++    if (f->total_tracks == 0)
++        return f->error++;
++
++    p_track = f->track[f->total_tracks - 1];
+     if (p_track->ctts_entry_count) return 0;
+ 
+     mp4ff_read_char(f); /* version */
+@@ -478,7 +528,7 @@ static int32_t mp4ff_read_ctts(mp4ff_t *f)
+     }
+     else
+     {
+-        for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
++        for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count && !f->stream->read_error; i++) /* CVE-2017-9257 */
+         {
+             p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
+             p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
+@@ -490,7 +540,13 @@ static int32_t mp4ff_read_ctts(mp4ff_t *f)
+ static int32_t mp4ff_read_stts(mp4ff_t *f)
+ {
+     int32_t i;
+-    mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
++    mp4ff_track_t * p_track;
++
++    /* CVE-2017-9223 */
++    if (f->total_tracks == 0)
++        return f->error++;
++
++    p_track = f->track[f->total_tracks - 1];
+ 
+     if (p_track->stts_entry_count) return 0;
+ 
+@@ -510,7 +566,7 @@ static int32_t mp4ff_read_stts(mp4ff_t *f)
+     }
+     else
+     {
+-        for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
++        for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count && !f->stream->read_error; i++) /* CVE-2017-9254 */
+         {
+             p_track->stts_sample_count[i] = mp4ff_read_int32(f);
+             p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
+@@ -597,6 +653,10 @@ static int32_t mp4ff_read_mdhd(mp4ff_t *f)
+ {
+     uint32_t version;
+ 
++    /* CVE-2017-9221 */
++    if (f->total_tracks == 0)
++        return f->error++;
++
+     version = mp4ff_read_int32(f);
+     if (version==1)
+     {
+diff --git a/common/mp4ff/mp4ff.c b/common/mp4ff/mp4ff.c
+index 9181ace..761bb0d 100644
+--- a/common/mp4ff/mp4ff.c
++++ b/common/mp4ff/mp4ff.c
+@@ -42,6 +42,12 @@ mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
+ 
+     parse_atoms(ff,0);
+ 
++    if (ff->error)
++    {
++        free(ff);
++        ff = NULL;
++    }
++
+     return ff;
+ }
+ 
+@@ -55,6 +61,12 @@ mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f)
+ 
+     parse_atoms(ff,1);
+ 
++    if (ff->error)
++    {
++        free(ff);
++        ff = NULL;
++    }
++
+     return ff;
+ }
+ 
+@@ -101,10 +113,17 @@ void mp4ff_close(mp4ff_t *ff)
+     if (ff) free(ff);
+ }
+ 
+-void mp4ff_track_add(mp4ff_t *f)
++static void mp4ff_track_add(mp4ff_t *f)
+ {
+     f->total_tracks++;
+ 
++    if (f->total_tracks > MAX_TRACKS)
++    {
++        f->total_tracks = 0;
++        f->error++;
++        return;
++    }
++
+     f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
+ 
+     memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
+@@ -185,6 +204,7 @@ int32_t parse_atoms(mp4ff_t *f,int meta_only)
+     uint8_t header_size = 0;
+ 
+     f->file_size = 0;
++    f->stream->read_error = 0;
+ 
+     while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
+     {
+diff --git a/common/mp4ff/mp4ff.h b/common/mp4ff/mp4ff.h
+index 17b7fe7..8c4b66c 100644
+--- a/common/mp4ff/mp4ff.h
++++ b/common/mp4ff/mp4ff.h
+@@ -47,12 +47,113 @@ typedef struct
+     uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
+     uint32_t (*write)(void *udata, void *buffer, uint32_t length);
+     uint32_t (*seek)(void *user_data, uint64_t position);
+-	uint32_t (*truncate)(void *user_data);
++    uint32_t (*truncate)(void *user_data);
+     void *user_data;
++    uint32_t read_error;
+ } mp4ff_callback_t;
+ 
++#ifdef USE_TAGGING
++
++/* metadata tag structure */
++typedef struct
++{
++    char *item;
++    char *value;
++    uint32_t len;
++} mp4ff_tag_t;
++
++/* metadata list structure */
++typedef struct
++{
++    mp4ff_tag_t *tags;
++    uint32_t count;
++} mp4ff_metadata_t;
++
++int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
++
++#endif
++
++
++#ifndef MP4FF_INTERNAL_H
+ /* mp4 main file structure */
+ typedef void* mp4ff_t;
++#else
++typedef struct
++{
++    int32_t type;
++    int32_t channelCount;
++    int32_t sampleSize;
++    uint16_t sampleRate;
++    int32_t audioType;
++
++    /* stsd */
++    int32_t stsd_entry_count;
++
++    /* stsz */
++    int32_t stsz_sample_size;
++    int32_t stsz_sample_count;
++    int32_t *stsz_table;
++
++    /* stts */
++    int32_t stts_entry_count;
++    int32_t *stts_sample_count;
++    int32_t *stts_sample_delta;
++
++    /* stsc */
++    int32_t stsc_entry_count;
++    int32_t *stsc_first_chunk;
++    int32_t *stsc_samples_per_chunk;
++    int32_t *stsc_sample_desc_index;
++
++    /* stsc */
++    int32_t stco_entry_count;
++    int32_t *stco_chunk_offset;
++
++    /* ctts */
++    int32_t ctts_entry_count;
++    int32_t *ctts_sample_count;
++    int32_t *ctts_sample_offset;
++
++    /* esde */
++    uint8_t *decoderConfig;
++    int32_t decoderConfigLen;
++
++    uint32_t maxBitrate;
++    uint32_t avgBitrate;
++
++    uint32_t timeScale;
++    uint64_t duration;
++
++} mp4ff_track_t;
++
++/* mp4 main file structure */
++typedef struct
++{
++    /* stream to read from */
++    mp4ff_callback_t *stream;
++    int64_t current_position;
++
++    int32_t moov_read;
++    uint64_t moov_offset;
++    uint64_t moov_size;
++    uint8_t last_atom;
++    uint64_t file_size;
++    uint32_t error;
++
++    /* mvhd */
++    int32_t time_scale;
++    int32_t duration;
++
++    /* incremental track index while reading the file */
++    int32_t total_tracks;
++
++    /* track data */
++    mp4ff_track_t *track[MAX_TRACKS];
++
++    /* metadata */
++    mp4ff_metadata_t tags;
++} mp4ff_t;
++#endif
+ 
+ 
+ /* API */
+@@ -110,26 +211,6 @@ int mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value);
+ int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
+ int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
+ int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
+-#ifdef USE_TAGGING
+-
+-/* metadata tag structure */
+-typedef struct
+-{
+-    char *item;
+-    char *value;
+-} mp4ff_tag_t;
+-
+-/* metadata list structure */
+-typedef struct
+-{
+-    mp4ff_tag_t *tags;
+-    uint32_t count;
+-} mp4ff_metadata_t;
+-
+-int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
+-
+-#endif
+-
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/common/mp4ff/mp4ffint.h b/common/mp4ff/mp4ffint.h
+index 8c5455c..152e13f 100644
+--- a/common/mp4ff/mp4ffint.h
++++ b/common/mp4ff/mp4ffint.h
+@@ -136,110 +136,7 @@ extern "C" {
+ #define strdup _strdup
+ #endif
+ 
+-/* file callback structure */
+-typedef struct
+-{
+-    uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
+-    uint32_t (*write)(void *udata, void *buffer, uint32_t length);
+-    uint32_t (*seek)(void *user_data, uint64_t position);
+-    uint32_t (*truncate)(void *user_data);
+-    void *user_data;
+-} mp4ff_callback_t;
+-
+-
+-/* metadata tag structure */
+-typedef struct
+-{
+-    char *item;
+-    char *value;
+-    uint32_t len;
+-} mp4ff_tag_t;
+-
+-/* metadata list structure */
+-typedef struct
+-{
+-    mp4ff_tag_t *tags;
+-    uint32_t count;
+-} mp4ff_metadata_t;
+-
+-
+-typedef struct
+-{
+-    int32_t type;
+-    int32_t channelCount;
+-    int32_t sampleSize;
+-    uint16_t sampleRate;
+-    int32_t audioType;
+-
+-    /* stsd */
+-    int32_t stsd_entry_count;
+-
+-    /* stsz */
+-    int32_t stsz_sample_size;
+-    int32_t stsz_sample_count;
+-    int32_t *stsz_table;
+-
+-    /* stts */
+-    int32_t stts_entry_count;
+-    int32_t *stts_sample_count;
+-    int32_t *stts_sample_delta;
+-
+-    /* stsc */
+-    int32_t stsc_entry_count;
+-    int32_t *stsc_first_chunk;
+-    int32_t *stsc_samples_per_chunk;
+-    int32_t *stsc_sample_desc_index;
+-
+-    /* stsc */
+-    int32_t stco_entry_count;
+-    int32_t *stco_chunk_offset;
+-
+-    /* ctts */
+-    int32_t ctts_entry_count;
+-    int32_t *ctts_sample_count;
+-    int32_t *ctts_sample_offset;
+-
+-    /* esde */
+-    uint8_t *decoderConfig;
+-    int32_t decoderConfigLen;
+-
+-    uint32_t maxBitrate;
+-    uint32_t avgBitrate;
+-
+-    uint32_t timeScale;
+-    uint64_t duration;
+-
+-} mp4ff_track_t;
+-
+-/* mp4 main file structure */
+-typedef struct
+-{
+-    /* stream to read from */
+-    mp4ff_callback_t *stream;
+-    int64_t current_position;
+-
+-    int32_t moov_read;
+-    uint64_t moov_offset;
+-    uint64_t moov_size;
+-    uint8_t last_atom;
+-    uint64_t file_size;
+-
+-    /* mvhd */
+-    int32_t time_scale;
+-    int32_t duration;
+-
+-    /* incremental track index while reading the file */
+-    int32_t total_tracks;
+-
+-    /* track data */
+-    mp4ff_track_t *track[MAX_TRACKS];
+-
+-    /* metadata */
+-    mp4ff_metadata_t tags;
+-} mp4ff_t;
+-
+-
+-
++#include "mp4ff.h"
+ 
+ /* mp4util.c */
+ int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
+diff --git a/common/mp4ff/mp4meta.c b/common/mp4ff/mp4meta.c
+index def2149..54117f5 100644
+--- a/common/mp4ff/mp4meta.c
++++ b/common/mp4ff/mp4meta.c
+@@ -240,7 +240,7 @@ static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const
+     uint32_t len = 0;
+ 
+ 
+-    while (sumsize < size)
++    while (sumsize < size && !f->stream->read_error) /* CVE-2017-9222 */
+     {
+ 		uint64_t destpos;
+         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
+@@ -500,4 +500,4 @@ int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
+     return mp4ff_meta_find_by_name_and_return_len(f, "cover", value);
+ }
+ 
+-#endif
+\ No newline at end of file
++#endif
+diff --git a/common/mp4ff/mp4util.c b/common/mp4ff/mp4util.c
+index 24d89c7..75a1620 100644
+--- a/common/mp4ff/mp4util.c
++++ b/common/mp4ff/mp4util.c
+@@ -37,6 +37,9 @@ int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size)
+ 
+     result = f->stream->read(f->stream->user_data, data, size);
+ 
++    if (result < size)
++        f->stream->read_error++;
++
+     f->current_position += size;
+ 
+     return result;
diff -Nru faad2-2.8.0~cvs20161113/debian/patches/series faad2-2.8.0~cvs20161113/debian/patches/series
--- faad2-2.8.0~cvs20161113/debian/patches/series	2016-11-05 21:07:00.000000000 +0100
+++ faad2-2.8.0~cvs20161113/debian/patches/series	2018-05-01 17:49:02.000000000 +0200
@@ -1 +1,2 @@
 reproducible-build.patch
+CVE-2017-92xx.patch

Reply to: