diff --git a/CVE-2020-22219-0001-fix-potential-memleak.patch b/CVE-2020-22219-0001-fix-potential-memleak.patch new file mode 100644 index 0000000..13c08e0 --- /dev/null +++ b/CVE-2020-22219-0001-fix-potential-memleak.patch @@ -0,0 +1,41 @@ +From b715d7b9fe90f5b411ae1c159553c7c287f0789a Mon Sep 17 00:00:00 2001 +From: lutianxiong +Date: Thu, 4 Jun 2020 14:58:06 +0800 +Subject: [PATCH] fix potential memleak + +Reference:https://github.com/xiph/flac/commit/b715d7b9fe90f5b411ae1c159553c7c287f0789a +--- + include/share/alloc.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/include/share/alloc.h b/include/share/alloc.h +index edd3a79e..9b53b010 100644 +--- a/include/share/alloc.h ++++ b/include/share/alloc.h +@@ -200,8 +200,10 @@ static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) + { + if(!size1 || !size2) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ +- if(size1 > SIZE_MAX / size2) ++ if(size1 > SIZE_MAX / size2) { ++ free(ptr); + return 0; ++ } + return safe_realloc_(ptr, size1*size2); + } + +@@ -211,8 +213,10 @@ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, + if(!size1 || (!size2 && !size3)) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + size2 += size3; +- if(size2 < size3) ++ if(size2 < size3) { ++ free(ptr); + return 0; ++ } + return safe_realloc_mul_2op_(ptr, size1, size2); + } + +-- +2.27.0 + diff --git a/CVE-2020-22219-0002-Add-and-use-_nofree-variants-of-safe_realloc-functio.patch b/CVE-2020-22219-0002-Add-and-use-_nofree-variants-of-safe_realloc-functio.patch new file mode 100644 index 0000000..7a1dc7c --- /dev/null +++ b/CVE-2020-22219-0002-Add-and-use-_nofree-variants-of-safe_realloc-functio.patch @@ -0,0 +1,195 @@ +From 21fe95ee828b0b9b944f6aa0bb02d24fbb981815 Mon Sep 17 00:00:00 2001 +From: Martijn van Beurden +Date: Wed, 3 Aug 2022 13:52:19 +0200 +Subject: [PATCH] Add and use _nofree variants of safe_realloc functions + +Parts of the code use realloc like + +x = safe_realloc(x, somesize); + +when this is the case, the safe_realloc variant used must free the +old memory block in case it fails, otherwise it will leak. However, +there are also instances in the code where handling is different: + +if (0 == (x = safe_realloc(y, somesize))) + return false + +in this case, y should not be freed, as y is not set to NULL we +could encounter double frees. Here the safe_realloc_nofree +functions are used. + +Reference:https://github.com/xiph/flac/commit/21fe95ee828b0b9b944f6aa0bb02d24fbb981815 +--- + include/share/alloc.h | 41 +++++++++++++++++++++++++++++++---- + src/flac/encode.c | 4 ++-- + src/flac/foreign_metadata.c | 2 +- + src/libFLAC/bitwriter.c | 2 +- + src/libFLAC/metadata_object.c | 2 +- + src/plugin_common/tags.c | 2 +- + src/share/utf8/iconvert.c | 2 +- + 7 files changed, 44 insertions(+), 11 deletions(-) + +diff --git a/include/share/alloc.h b/include/share/alloc.h +index 9b53b010..74f444d6 100644 +--- a/include/share/alloc.h ++++ b/include/share/alloc.h +@@ -161,17 +161,30 @@ static inline void *safe_realloc_(void *ptr, size_t size) + free(oldptr); + return newptr; + } +-static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) ++static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2) ++{ ++ size2 += size1; ++ if(size2 < size1) ++ return 0; ++ return realloc(ptr, size2); ++} ++ ++static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) + { + size2 += size1; + if(size2 < size1) { + free(ptr); + return 0; + } +- return realloc(ptr, size2); ++ size3 += size2; ++ if(size3 < size2) { ++ free(ptr); ++ return 0; ++ } ++ return safe_realloc_(ptr, size3); + } + +-static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) ++static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) + { + size2 += size1; + if(size2 < size1) +@@ -182,7 +195,7 @@ static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, + return realloc(ptr, size3); + } + +-static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) ++static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) + { + size2 += size1; + if(size2 < size1) +@@ -207,6 +220,15 @@ static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) + return safe_realloc_(ptr, size1*size2); + } + ++static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2) ++{ ++ if(!size1 || !size2) ++ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ ++ if(size1 > SIZE_MAX / size2) ++ return 0; ++ return realloc(ptr, size1*size2); ++} ++ + /* size1 * (size2 + size3) */ + static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) + { +@@ -220,4 +242,15 @@ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, + return safe_realloc_mul_2op_(ptr, size1, size2); + } + ++/* size1 * (size2 + size3) */ ++static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) ++{ ++ if(!size1 || (!size2 && !size3)) ++ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ ++ size2 += size3; ++ if(size2 < size3) ++ return 0; ++ return safe_realloc_nofree_mul_2op_(ptr, size1, size2); ++} ++ + #endif +diff --git a/src/flac/encode.c b/src/flac/encode.c +index a7d1f7b2..b82ced76 100644 +--- a/src/flac/encode.c ++++ b/src/flac/encode.c +@@ -1734,10 +1734,10 @@ static void static_metadata_clear(static_metadata_t *m) + static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete) + { + void *x; +- if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/))) ++ if(0 == (x = safe_realloc_nofree_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/))) + return false; + m->metadata = (FLAC__StreamMetadata**)x; +- if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/))) ++ if(0 == (x = safe_realloc_nofree_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/))) + return false; + m->needs_delete = (FLAC__bool*)x; + m->metadata[m->num_metadata] = d; +diff --git a/src/flac/foreign_metadata.c b/src/flac/foreign_metadata.c +index 9a1fb96c..c86dff42 100644 +--- a/src/flac/foreign_metadata.c ++++ b/src/flac/foreign_metadata.c +@@ -74,7 +74,7 @@ static FLAC__bool copy_data_(FILE *fin, FILE *fout, size_t size, const char **er + + static FLAC__bool append_block_(foreign_metadata_t *fm, FLAC__off_t offset, FLAC__uint32 size, const char **error) + { +- foreign_block_t *fb = safe_realloc_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/); ++ foreign_block_t *fb = safe_realloc_nofree_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/); + if(fb) { + fb[fm->num_blocks].offset = offset; + fb[fm->num_blocks].size = size; +diff --git a/src/libFLAC/bitwriter.c b/src/libFLAC/bitwriter.c +index 79ab8649..8865a2f4 100644 +--- a/src/libFLAC/bitwriter.c ++++ b/src/libFLAC/bitwriter.c +@@ -133,7 +133,7 @@ FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, uint32_t bits_to_add) + FLAC__ASSERT(new_capacity > bw->capacity); + FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); + +- new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); ++ new_buffer = safe_realloc_nofree_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); + if(new_buffer == 0) + return false; + bw->buffer = new_buffer; +diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c +index 7cc8ee9f..2c7da8db 100644 +--- a/src/libFLAC/metadata_object.c ++++ b/src/libFLAC/metadata_object.c +@@ -98,7 +98,7 @@ static FLAC__bool free_copy_bytes_(FLAC__byte **to, const FLAC__byte *from, uint + /* realloc() failure leaves entry unchanged */ + static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, uint32_t length) + { +- FLAC__byte *x = safe_realloc_add_2op_(*entry, length, /*+*/1); ++ FLAC__byte *x = safe_realloc_nofree_add_2op_(*entry, length, /*+*/1); + if (x != NULL) { + x[length] = '\0'; + *entry = x; +diff --git a/src/plugin_common/tags.c b/src/plugin_common/tags.c +index e9227444..ffd846b6 100644 +--- a/src/plugin_common/tags.c ++++ b/src/plugin_common/tags.c +@@ -317,7 +317,7 @@ FLAC__bool FLAC_plugin__tags_add_tag_utf8(FLAC__StreamMetadata *tags, const char + const size_t value_len = strlen(value); + const size_t separator_len = strlen(separator); + FLAC__byte *new_entry; +- if(0 == (new_entry = safe_realloc_add_4op_(entry->entry, entry->length, /*+*/value_len, /*+*/separator_len, /*+*/1))) ++ if(0 == (new_entry = safe_realloc_nofree_add_4op_(entry->entry, entry->length, /*+*/value_len, /*+*/separator_len, /*+*/1))) + return false; + memcpy(new_entry+entry->length, separator, separator_len); + entry->length += separator_len; +diff --git a/src/share/utf8/iconvert.c b/src/share/utf8/iconvert.c +index 8ab53c10..876c06e8 100644 +--- a/src/share/utf8/iconvert.c ++++ b/src/share/utf8/iconvert.c +@@ -149,7 +149,7 @@ int iconvert(const char *fromcode, const char *tocode, + iconv_close(cd1); + return ret; + } +- newbuf = safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1); ++ newbuf = safe_realloc_nofree_add_2op_(utfbuf, (ob - utfbuf), /*+*/1); + if (!newbuf) + goto fail; + ob = (ob - utfbuf) + newbuf; +-- +2.27.0 + diff --git a/CVE-2020-22219-0003-Leave-metadata-items-untouched-if-resize-function-fa.patch b/CVE-2020-22219-0003-Leave-metadata-items-untouched-if-resize-function-fa.patch new file mode 100644 index 0000000..20c08e5 --- /dev/null +++ b/CVE-2020-22219-0003-Leave-metadata-items-untouched-if-resize-function-fa.patch @@ -0,0 +1,129 @@ +From 707dace4bd82cd6042e524c72544ab50de223a10 Mon Sep 17 00:00:00 2001 +From: Martijn van Beurden +Date: Wed, 3 Aug 2022 19:23:46 +0200 +Subject: [PATCH] Leave metadata items untouched if resize function fails + +Conflict: delete the comment from the include/FLAC/all.h file. +Reference: https://github.com/xiph/flac/commit/707dace4bd82cd6042e524c72544ab50de223a10 + +--- + include/FLAC/metadata.h | 12 ++++++++---- + src/libFLAC/metadata_object.c | 36 ++++++++++++++++++++++++----------- + 2 files changed, 33 insertions(+), 15 deletions(-) + +diff --git a/include/FLAC/metadata.h b/include/FLAC/metadata.h +index aa369054..bf1bffe4 100644 +--- a/include/FLAC/metadata.h ++++ b/include/FLAC/metadata.h +@@ -1398,7 +1398,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetad + /** Resize the seekpoint array. + * + * If the size shrinks, elements will truncated; if it grows, new placeholder +- * points will be added to the end. ++ * points will be added to the end. If this function returns false, the ++ * object is left untouched. + * + * \param object A pointer to an existing SEEKTABLE object. + * \param new_num_points The desired length of the array; may be \c 0. +@@ -1611,7 +1612,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__ + /** Resize the comment array. + * + * If the size shrinks, elements will truncated; if it grows, new empty +- * fields will be added to the end. ++ * fields will be added to the end. If this function returns false, the ++ * object is left untouched. + * + * \param object A pointer to an existing VORBIS_COMMENT object. + * \param new_num_comments The desired length of the array; may be \c 0. +@@ -1891,7 +1893,8 @@ FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_C + /** Resize a track's index point array. + * + * If the size shrinks, elements will truncated; if it grows, new blank +- * indices will be added to the end. ++ * indices will be added to the end. If this function returns false, the ++ * track object is left untouched. + * + * \param object A pointer to an existing CUESHEET object. + * \param track_num The index of the track to modify. NOTE: this is not +@@ -1977,7 +1980,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__Stre + /** Resize the track array. + * + * If the size shrinks, elements will truncated; if it grows, new blank +- * tracks will be added to the end. ++ * tracks will be added to the end. If this function returns false, the ++ * object is left untouched. + * + * \param object A pointer to an existing CUESHEET object. + * \param new_num_tracks The desired length of the array; may be \c 0. +diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c +index 2c7da8db..d6ac3fc5 100644 +--- a/src/libFLAC/metadata_object.c ++++ b/src/libFLAC/metadata_object.c +@@ -952,8 +952,13 @@ FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMe + free(object->data.seek_table.points); + object->data.seek_table.points = 0; + } +- else if ((object->data.seek_table.points = safe_realloc_(object->data.seek_table.points, new_size)) == NULL) +- return false; ++ else { ++ /* Leave object->data.seek_table.points untouched if realloc fails */ ++ FLAC__StreamMetadata_SeekPoint *tmpptr; ++ if ((tmpptr = realloc(object->data.seek_table.points, new_size)) == NULL) ++ return false; ++ object->data.seek_table.points = tmpptr; ++ } + + /* if growing, set new elements to placeholders */ + if (new_size > old_size) { +@@ -1207,12 +1212,11 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__St + object->data.vorbis_comment.comments = 0; + } + else { +- FLAC__StreamMetadata_VorbisComment_Entry *oldptr = object->data.vorbis_comment.comments; +- if ((object->data.vorbis_comment.comments = realloc(object->data.vorbis_comment.comments, new_size)) == NULL) { +- vorbiscomment_entry_array_delete_(oldptr, object->data.vorbis_comment.num_comments); +- object->data.vorbis_comment.num_comments = 0; ++ /* Leave object->data.vorbis_comment.comments untouched if realloc fails */ ++ FLAC__StreamMetadata_VorbisComment_Entry *tmpptr; ++ if ((tmpptr = realloc(object->data.vorbis_comment.comments, new_size)) == NULL) + return false; +- } ++ object->data.vorbis_comment.comments = tmpptr; + } + + /* if growing, zero all the length/pointers of new elements */ +@@ -1520,8 +1524,13 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__St + free(track->indices); + track->indices = 0; + } +- else if ((track->indices = safe_realloc_(track->indices, new_size)) == NULL) +- return false; ++ else { ++ /* Leave track->indices untouched if realloc fails */ ++ FLAC__StreamMetadata_CueSheet_Index *tmpptr; ++ if ((tmpptr = realloc(track->indices, new_size)) == NULL) ++ return false; ++ track->indices = tmpptr; ++ } + + /* if growing, zero all the lengths/pointers of new elements */ + if (new_size > old_size) +@@ -1615,8 +1624,13 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMet + free(object->data.cue_sheet.tracks); + object->data.cue_sheet.tracks = 0; + } +- else if ((object->data.cue_sheet.tracks = safe_realloc_(object->data.cue_sheet.tracks, new_size)) == NULL) +- return false; ++ else { ++ /* Leave object->data.cue_sheet.tracks untouched if realloc fails */ ++ FLAC__StreamMetadata_CueSheet_Track *tmpptr; ++ if ((tmpptr = realloc(object->data.cue_sheet.tracks, new_size)) == NULL) ++ return false; ++ object->data.cue_sheet.tracks = tmpptr; ++ } + + /* if growing, zero all the lengths/pointers of new elements */ + if (new_size > old_size) +-- +2.27.0 + diff --git a/flac.spec b/flac.spec index fbe87e2..b57c4cd 100644 --- a/flac.spec +++ b/flac.spec @@ -2,7 +2,7 @@ Name: flac Version: 1.3.4 -Release: 1 +Release: 2 Summary: encoder/decoder which support the Free Lossless Audio Codec License: BSD and GPLv2+ and GFDL Source0: http://downloads.xiph.org/releases/flac/flac-%{version}.tar.xz @@ -11,6 +11,9 @@ URL: http://www.xiph.org/flac/ %ifarch sw_64 Patch0000: flac-1.3.4-sw.patch %endif +Patch0001: CVE-2020-22219-0001-fix-potential-memleak.patch +Patch0002: CVE-2020-22219-0002-Add-and-use-_nofree-variants-of-safe_realloc-functio.patch +Patch0003: CVE-2020-22219-0003-Leave-metadata-items-untouched-if-resize-function-fa.patch Provides: %{name}-libs Obsoletes: %{name}-libs @@ -102,6 +105,9 @@ update-desktop-database &> /dev/null || : %doc flac-doc-devel/* %changelog +* Tue Aug 29 2023 chenhaixiang - 1.3.4-2 +- fix CVE-2020-22219 + * Wed Nov 9 2022 chenhaixiang - 1.3.4-1 - update to 1.3.4