Bug#867724: Multiple security issues
Markus Koschany
apo at debian.org
Wed Aug 30 20:23:08 UTC 2017
On Sun, 27 Aug 2017 21:29:43 +0200 Fabian Greffrath <fabian at debian.org>
wrote:
> Am Sonntag, den 27.08.2017, 20:33 +0200 schrieb Markus Koschany:
> > Are you aware of any issues with your patch?
>
> Yes, there was an issue with my patch! I added a field to a struct to
> keep track of reading errors, but the struct was defined in two
> different places in the source code. This led to a crash when free()ing
> a pointer to this struct on Linux, but not on Windows which I used to
> develop the patch (don't ask).
>
> Applying this patch on top of the one I sent to the Debian BTS should
> fix this issue, although upstream decided to go a different way
> and entirely replace the mp4ff library.
>
> https://sourceforge.net/p/faac/bugs/209/?limit=25&page=1#d838
>
> - Fabian
Hi,
I uploaded a security update for faad2 to wheezy-security a few hours
ago. I am attaching the debdiff to this bug report.
Do you intend to fix the issue in Stretch too? I could prepare the
update for Jessie and ask the release team for a jessie-pu.
Markus
-------------- next part --------------
diff -Nru faad2-2.7/debian/changelog faad2-2.7/debian/changelog
--- faad2-2.7/debian/changelog 2012-03-18 14:08:08.000000000 +0100
+++ faad2-2.7/debian/changelog 2017-08-30 20:07:59.000000000 +0200
@@ -1,3 +1,15 @@
+faad2 (2.7-8+deb7u1) wheezy-security; urgency=high
+
+ * Non-maintainer upload by the LTS team.
+ * 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.
+
+ -- Markus Koschany <apo at debian.org> Wed, 30 Aug 2017 20:07:59 +0200
+
faad2 (2.7-8) unstable; urgency=low
[ Fabian Greffrath ]
diff -Nru faad2-2.7/debian/patches/CVE-2017-92xx.patch faad2-2.7/debian/patches/CVE-2017-92xx.patch
--- faad2-2.7/debian/patches/CVE-2017-92xx.patch 1970-01-01 01:00:00.000000000 +0100
+++ faad2-2.7/debian/patches/CVE-2017-92xx.patch 2017-08-30 20:07:59.000000000 +0200
@@ -0,0 +1,551 @@
+From: Markus Koschany <apo at debian.org>
+Date: Tue, 29 Aug 2017 22:04:32 +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 | 104 +---------------------------------------
+ common/mp4ff/mp4meta.c | 4 +-
+ common/mp4ff/mp4util.c | 3 ++
+ 6 files changed, 197 insertions(+), 135 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 c92b588..2530205 100644
+--- a/common/mp4ff/mp4ffint.h
++++ b/common/mp4ff/mp4ffint.h
+@@ -136,109 +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;
+-} 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 3e08be3..98340a3 100644
+--- a/common/mp4ff/mp4meta.c
++++ b/common/mp4ff/mp4meta.c
+@@ -228,7 +228,7 @@ static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const
+ uint32_t done = 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);
+@@ -458,4 +458,4 @@ int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value)
+ return mp4ff_meta_find_by_name(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.7/debian/patches/series faad2-2.7/debian/patches/series
--- faad2-2.7/debian/patches/series 2012-03-16 22:08:17.000000000 +0100
+++ faad2-2.7/debian/patches/series 2017-08-30 20:07:59.000000000 +0200
@@ -5,3 +5,4 @@
path_max.patch
fix_ftbfs_with_gcc4.5.patch
symbol-visibility.patch
+CVE-2017-92xx.patch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 963 bytes
Desc: OpenPGP digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-multimedia-maintainers/attachments/20170830/aff19344/attachment-0001.sig>
More information about the pkg-multimedia-maintainers
mailing list