WIN9X: Bring FLAC support back, through FLAC 1.2.1 (with patches)

Current FLAC expects `_stat64` to always be available on Windows, but
that's not the case for Win9x.

Moreover, even FLAC 1.3.2 in 2017 started to "Assume all currently
used OSes support SSE2", so it's getting harder and harder to have
a modern FLAC running on old Windows releases.

FLAC 1.2.1 appears to do the job, though (with some patches).
It's old (2007), but if your target is a 1995 OS, it shouldn't be
too bad.

Also apply CVE-2014-9028 FLAC patches from CentOS.
It appears that CentOS 7 used later upstream patches for CVE-2014-9028,
which provide a better fix, and prevent seeking bugs resulting from the
first fixes.
This commit is contained in:
dwa
2025-04-24 12:35:13 +02:00
committed by GitHub
parent 1657091c5f
commit 7ed57f4b34
11 changed files with 651 additions and 3 deletions
+6 -3
View File
@@ -58,9 +58,12 @@ helpers_package(libvorbis)
helpers_package(libtheora)
# FLAC is not compatible with Win9x due to missing functions in MSVCRT.DLL
# _fstat64, _stat64, _wstat64, _wutime64
# helpers_package(flac)
# Modern FLAC is not compatible with Win9x due to missing functions in MSVCRT.DLL
# _fstat64, _stat64, _wstat64, _wutime64. FLAC 1.3.2+ also "assume all currently
# used OSes support SSE2", which is not good news for Windows 95 or 98.
#
# On the other hand, various users expect FLAC to work, so use an older release
local_package(flac)
helpers_package(libmikmod)
+23
View File
@@ -0,0 +1,23 @@
#! /bin/sh
# Last release where Windows 95 support appears to be possible
FLAC_VERSION=1.2.1
FLAC_SHA256=9635a44bceb478bbf2ee8a785cf6986fba525afb5fad1fd4bba73cf71f2d3edf
PACKAGE_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
HELPERS_DIR=$PACKAGE_DIR/../..
. $HELPERS_DIR/functions.sh
do_make_bdir
do_http_fetch flac "http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.gz" \
'tar xzf' "sha256:${FLAC_SHA256}"
autoreconf -fi -I m4
do_configure --disable-doxygen-docs --disable-xmms-plugin --disable-cpplibs --disable-ogg "$@"
do_make -C src/libFLAC
do_make -C src/libFLAC install
# No need to build includes
do_make -C include install
do_clean_bdir
@@ -0,0 +1,42 @@
From 2ad89eebba092c21377f8447e2192c123dbad4ad Mon Sep 17 00:00:00 2001
From: Le Philousophe <lephilousophe@users.noreply.github.com>
Date: Sun, 10 Oct 2021 19:21:57 +0200
Subject: [PATCH] Fix for newer Gettext not providing the macro
---
m4/codeset.m4 | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 m4/codeset.m4
diff --git a/m4/codeset.m4 b/m4/codeset.m4
new file mode 100644
index 00000000..cf53d241
--- /dev/null
+++ b/m4/codeset.m4
@@ -0,0 +1,23 @@
+# codeset.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2006, 2008-2012 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_LANGINFO_CODESET],
+[
+ AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <langinfo.h>]],
+ [[char* cs = nl_langinfo(CODESET); return !cs;]])],
+ [am_cv_langinfo_codeset=yes],
+ [am_cv_langinfo_codeset=no])
+ ])
+ if test $am_cv_langinfo_codeset = yes; then
+ AC_DEFINE([HAVE_LANGINFO_CODESET], [1],
+ [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
+ fi
+])
--
2.32.0
@@ -0,0 +1,11 @@
--- a/include/share/alloc.h
+++ b/include/share/alloc.h
@@ -28,7 +28,7 @@
*/
#include <limits.h> /* for SIZE_MAX */
-#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
+#ifdef HAVE_STDINT_H
#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
#endif
#include <stdlib.h> /* for size_t, malloc(), etc */
@@ -0,0 +1,256 @@
Bring various asm bugfixes from FLAC 1.3.x, mainly targeted at older CPUs,
which is what some users of theses Win95 releases could possibly use
From https://github.com/xiph/flac/commits/1.3.4/src/libFLAC/ia32:
* commit 08bfd42: fix labels (missing colons)
* commit 3cea079: Fix a couple of NASM warnings
* commit 8e4a45a: Match calls and returns
* commit c2747be: More 'mov cl' -> 'mov ecx' fixes
* commit 2c15052: CPUID detecion improvements
* commit c12bfa0: Fix cpuid detecton on old Cyrix CPUs
--- a/src/libFLAC/ia32/cpu_asm.nasm
+++ b/src/libFLAC/ia32/cpu_asm.nasm
@@ -46,7 +46,6 @@
;
cident FLAC__cpu_have_cpuid_asm_ia32
- push ebx
pushfd
pop eax
mov edx, eax
@@ -55,14 +54,11 @@
popfd
pushfd
pop eax
- cmp eax, edx
- jz .no_cpuid
- mov eax, 1
- jmp .end
-.no_cpuid:
- xor eax, eax
-.end:
- pop ebx
+ xor eax, edx
+ and eax, 0x00200000
+ shr eax, 0x15
+ push edx
+ popfd
ret
; **********************************************************************
@@ -78,6 +74,11 @@
call FLAC__cpu_have_cpuid_asm_ia32
test eax, eax
jz .no_cpuid
+ mov eax, 0
+ cpuid
+ cmp eax, 1
+ jb .no_cpuid
+ xor ecx, ecx
mov eax, 1
cpuid
mov ebx, [esp + 8]
@@ -85,13 +86,13 @@
mov ebx, [esp + 12]
mov [ebx], ecx
jmp .end
-.no_cpuid
+.no_cpuid:
xor eax, eax
mov ebx, [esp + 8]
mov [ebx], eax
mov ebx, [esp + 12]
mov [ebx], eax
-.end
+.end:
pop ebx
ret
@@ -108,13 +109,13 @@
cpuid
mov eax, edx
jmp .end
-.no_cpuid
+.no_cpuid:
xor eax, eax
-.end
+.end:
pop ebx
ret
-end
+; end
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack noalloc
--- a/src/libFLAC/ia32/lpc_asm.nasm
+++ b/src/libFLAC/ia32/lpc_asm.nasm
@@ -113,9 +113,8 @@
lea edx, [eax + eax*2]
neg edx
lea edx, [eax + edx*4 + .jumper1_0 - .get_eip1]
- call .get_eip1
+ call .mov_eip_to_ebx
.get_eip1:
- pop ebx
add edx, ebx
inc edx ; compensate for the shorter opcode on the last iteration
inc edx ; compensate for the shorter opcode on the last iteration
@@ -126,6 +125,10 @@
.loop1_start:
jmp edx
+.mov_eip_to_ebx:
+ mov ebx, [esp]
+ ret
+
fld st0 ; ST = d d
fmul dword [esi + (32*4)] ; ST = d*data[sample+32] d WATCHOUT: not a byte displacement here!
fadd dword [edi + (32*4)] ; ST = autoc[32]+d*data[sample+32] d WATCHOUT: not a byte displacement here!
@@ -283,9 +286,8 @@
lea edx, [eax + eax*2]
neg edx
lea edx, [eax + edx*4 + .jumper2_0 - .get_eip2]
- call .get_eip2
+ call .mov_eip_to_ebx
.get_eip2:
- pop ebx
add edx, ebx
inc edx ; compensate for the shorter opcode on the last iteration
inc edx ; compensate for the shorter opcode on the last iteration
@@ -777,7 +779,7 @@
mov ecx, [esp + 28]
mov edx, [ecx] ; edx = qlp_coeff[0]
mov eax, [esi - 4] ; eax = data[-1]
- mov cl, [esp + 36] ; cl = lp_quantization
+ mov ecx, [esp + 36] ; cl = lp_quantization
ALIGN 16
.i_1_loop_i:
imul eax, edx
@@ -815,7 +817,7 @@
inc ecx
jnz short .i_32more_loop_j
- mov cl, [esp + 36]
+ mov ecx, [esp + 36]
sar ebp, cl
neg ebp
add ebp, [esi]
@@ -828,13 +830,16 @@
jmp .end
+.mov_eip_to_eax:
+ mov eax, [esp]
+ ret
+
.i_32:
sub edi, esi
neg eax
lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0]
- call .get_eip0
+ call .mov_eip_to_eax
.get_eip0:
- pop eax
add edx, eax
inc edx
mov eax, [esp + 28] ; eax = qlp_coeff[]
@@ -939,7 +944,7 @@
add ebp, ecx
.jumper_0:
- mov cl, [esp + 36]
+ mov ecx, [esp + 36]
sar ebp, cl
neg ebp
add ebp, [esi]
@@ -1184,7 +1189,7 @@
mov ecx, [esp + 28]
mov edx, [ecx]
mov eax, [edi - 4]
- mov cl, [esp + 36]
+ mov ecx, [esp + 36]
ALIGN 16
.x87_1_loop_i:
imul eax, edx
@@ -1220,7 +1225,7 @@
inc ecx
jnz short .x87_32more_loop_j
- mov cl, [esp + 36]
+ mov ecx, [esp + 36]
sar ebp, cl
add ebp, [esi]
mov [edi], ebp
@@ -1232,13 +1237,16 @@
jmp .end
+.mov_eip_to_eax:
+ mov eax, [esp]
+ ret
+
.x87_32:
sub esi, edi
neg eax
lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0]
- call .get_eip0
+ call .mov_eip_to_eax
.get_eip0:
- pop eax
add edx, eax
inc edx ; compensate for the shorter opcode on the last iteration
mov eax, [esp + 28] ; eax = qlp_coeff[]
@@ -1343,7 +1351,7 @@
add ebp, ecx ; sum += qlp_coeff[ 0] * data[i- 1]
.jumper_0:
- mov cl, [esp + 36]
+ mov ecx, [esp + 36]
sar ebp, cl ; ebp = (sum >> lp_quantization)
add ebp, [esi + edi] ; ebp = residual[i] + (sum >> lp_quantization)
mov [edi], ebp ; data[i] = residual[i] + (sum >> lp_quantization)
@@ -1504,7 +1512,7 @@
pop ebp
ret
-end
+; end
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack noalloc
--- a/src/libFLAC/ia32/bitreader_asm.nasm
+++ b/src/libFLAC/ia32/bitreader_asm.nasm
@@ -561,7 +561,7 @@
pop ebp
ret
-end
+; end
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack noalloc
--- a/src/libFLAC/ia32/fixed_asm.nasm
+++ b/src/libFLAC/ia32/fixed_asm.nasm
@@ -305,7 +305,7 @@
pop ebp
ret
-end
+; end
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack noalloc
--- a/src/libFLAC/ia32/stream_encoder_asm.nasm
+++ b/src/libFLAC/ia32/stream_encoder_asm.nasm
@@ -152,7 +152,7 @@
pop ebp
ret
-end
+; end
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack noalloc
@@ -0,0 +1,72 @@
avoid an unnecessary dependency on ntohl(); we'd rather avoid linking to a
library just for that
--- a/configure.in
+++ b/configure.in
@@ -83,11 +83,7 @@
esac
AC_SUBST(OBJ_FORMAT)
-# only needed because of ntohl() usage, can get rid of after that's gone:
-case "$host" in
- *-*-cygwin|*mingw*) MINGW_WINSOCK_LIBS=-lwsock32 ;;
- *) MINGW_WINSOCK_LIBS= ;;
-esac
+MINGW_WINSOCK_LIBS=
AC_SUBST(MINGW_WINSOCK_LIBS)
case "$host" in
--- a/src/libFLAC/bitreader.c
+++ b/src/libFLAC/bitreader.c
@@ -35,15 +35,6 @@
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcpy(), memset() */
-#ifdef _MSC_VER
-#include <winsock.h> /* for ntohl() */
-#elif defined FLAC__SYS_DARWIN
-#include <machine/endian.h> /* for ntohl() */
-#elif defined __MINGW32__
-#include <winsock.h> /* for ntohl() */
-#else
-#include <netinet/in.h> /* for ntohl() */
-#endif
#include "private/bitmath.h"
#include "private/bitreader.h"
#include "private/crc.h"
@@ -64,7 +55,7 @@
#ifdef _MSC_VER
#define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x)
#else
-#define SWAP_BE_WORD_TO_HOST(x) ntohl(x)
+#define SWAP_BE_WORD_TO_HOST(x) __builtin_bswap32(x)
#endif
#endif
/* counts the # of zero MSBs in a word */
--- a/src/libFLAC/bitwriter.c
+++ b/src/libFLAC/bitwriter.c
@@ -35,15 +35,6 @@
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcpy(), memset() */
-#ifdef _MSC_VER
-#include <winsock.h> /* for ntohl() */
-#elif defined FLAC__SYS_DARWIN
-#include <machine/endian.h> /* for ntohl() */
-#elif defined __MINGW32__
-#include <winsock.h> /* for ntohl() */
-#else
-#include <netinet/in.h> /* for ntohl() */
-#endif
#if 0 /* UNUSED */
#include "private/bitmath.h"
#endif
@@ -66,7 +57,7 @@
#ifdef _MSC_VER
#define SWAP_BE_WORD_TO_HOST(x) local_swap32_(x)
#else
-#define SWAP_BE_WORD_TO_HOST(x) ntohl(x)
+#define SWAP_BE_WORD_TO_HOST(x) __builtin_bswap32(x)
#endif
#endif
@@ -0,0 +1,19 @@
Description: Memory leak at line in metadata_iterators.c, 'node' is not freed.
From: https://sourceforge.net/tracker/?func=detail&aid=2946736&group_id=13478&atid=313478
(from Debian Wheezy)
---
src/libFLAC/metadata_iterators.c | 1 +
1 file changed, 1 insertion(+)
--- a/src/libFLAC/metadata_iterators.c
+++ b/src/libFLAC/metadata_iterators.c
@@ -1217,6 +1217,7 @@ static FLAC__bool chain_read_cb_(FLAC__M
}
if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) {
+ node_delete_(node);
chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR;
return false;
}
@@ -0,0 +1,38 @@
From 5b3033a2b355068c11fe637e14ac742d273f076e Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Tue, 18 Nov 2014 07:20:25 -0800
Subject: [PATCH] src/libFLAC/stream_decoder.c : Fix buffer read overflow.
This is CVE-2014-8962.
Reported-by: Michele Spagnuolo,
Google Security Team <mikispag@google.com>
(from Debian Wheezy)
---
src/libFLAC/stream_decoder.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -94,7 +94,7 @@
*
***********************************************************************/
-static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
+static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
/***********************************************************************
*
@@ -1386,6 +1386,10 @@
id = 0;
continue;
}
+
+ if(id >= 3)
+ return false;
+
if(x == ID3V2_TAG_[id]) {
id++;
i = 0;
@@ -0,0 +1,111 @@
CVE-2014-9028 and related fixes
(from CentOS 7; flac-1.3.0-5.el7_1)
Merged four commits:
commit fcf0ba06ae12ccd7c67cee3c8d948df15f946b85
Author: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Wed Nov 19 19:35:59 2014 -0800
src/libFACL/stream_decoder.c : Fail safely to avoid a heap overflow.
A file provided by the reporters caused the stream decoder to write to
un-allocated heap space resulting in a segfault. The solution is to
error out (by returning false from read_residual_partitioned_rice_())
instead of trying to continue to decode.
Fixes: CVE-2014-9028
Reported-by: Michele Spagnuolo,
Google Security Team <mikispag@google.com>
commit 5a365996d739bdf4711af51d9c2c71c8a5e14660
Author: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Thu Nov 27 11:55:11 2014 +1100
src/libFLAC/stream_decoder.c : Fail safely to avoid a heap overflow.
This fix is closely related to the fix for CVE-2014-9028. When that
fix went public Miroslav Lichvar noticed a similar potential problem
spot in the same function and was able to craft a file to trigger a
heap write overflow.
Reported-by : Miroslav Lichvar <mlichvar@redhat.com>
commit b4b2910bdca010808ccf2799f55562fa91f4347b
Author: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Wed Dec 10 18:54:16 2014 +1100
src/libFLAC/stream_decoder.c : Fix seek bug.
Janne Hyvärinen reported a problem with seeking as a result of the
fix for CVE-2014-9028. This is a different solution to the issue
that should not adversely affect seeking.
This version of the fix for the above CVE has been extensively fuzz
tested using afl (http://lcamtuf.coredump.cx/afl/).
Reported-by: Janne Hyvärinen <cse@sci.fi>
commit fed0dfa1086296df0af41ca8f0c6430d5ac75c87
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Dec 15 15:46:12 2014 +0100
src/libFLAC/stream_decoder.c : Rework fix for seeking bug.
To avoid crash caused by an unbound LPC decoding when predictor order is
larger than blocksize, the sanity check needs to be moved to the subframe
decoding functions.
Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com>
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -2576,6 +2576,11 @@
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
return false; /* read_callback_ sets the state for us */
+ if(decoder->private_->frame.header.blocksize >> u32 < order) {
+ send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
+ decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
subframe->entropy_coding_method.data.partitioned_rice.order = u32;
subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
break;
@@ -2655,6 +2660,11 @@
case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2:
if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
return false; /* read_callback_ sets the state for us */
+ if(decoder->private_->frame.header.blocksize >> u32 < order) {
+ send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
+ decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
+ return true;
+ }
subframe->entropy_coding_method.data.partitioned_rice.order = u32;
subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel];
break;
@@ -2730,21 +2740,8 @@
const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN;
const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER;
- /* sanity checks */
- if(partition_order == 0) {
- if(decoder->private_->frame.header.blocksize < predictor_order) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- }
- else {
- if(partition_samples < predictor_order) {
- send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
- decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
- return true;
- }
- }
+ /* invalid predictor and partition orders mush be handled in the callers */
+ FLAC__ASSERT(partition_order > 0? partition_samples >= predictor_order : decoder->private_->frame.header.blocksize >= predictor_order);
if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
@@ -0,0 +1,33 @@
This replicates the same disable_sse_win95.patch used for libsdl1.2
i.e. when running on Windows 95, never use SSE, as the OS doesn't support it
--- a/src/libFLAC/cpu.c
+++ b/src/libFLAC/cpu.c
@@ -100,6 +100,10 @@
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
+#if defined(_WIN32) && !defined(_WIN32_WCE)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> /* For Win95 check */
+#endif
/*
* Extra stuff needed for detection of OS support for SSE on IA-32
@@ -217,6 +221,15 @@
#if defined FLAC__NO_SSE_OS
/* assume user knows better than us; turn it off */
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
+#elif defined(_WIN32) && !defined(_WIN32_WCE)
+ OSVERSIONINFO versionInfo;
+ memset(&versionInfo, 0, sizeof(versionInfo));
+ versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+ GetVersionEx(&versionInfo);
+
+ /* Is Win95? */
+ if(versionInfo.dwMajorVersion == 4 && versionInfo.dwMinorVersion == 0)
+ info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false;
#elif defined FLAC__SSE_OS
/* assume user knows better than us; leave as detected above */
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
@@ -0,0 +1,40 @@
From 43ba7ad05f1656e885ce2f34a9a72494f45705ae Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Fri, 28 Nov 2014 23:39:25 +1100
Subject: [PATCH] src/libFLAC/stream_decoder.c : Fix another input validation bug.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit
If a file says it contains a stupidly large number of vorbis comments,
the stream decoder would try to allocate enough memory which would fail
returning NULL and then write to that pointer anyway. The solution is
to set a hard limit of 10000 vorbis comments and force num_comments to
zero if the number is too large.
Problem found using the afl (american fuzzy lop) fuzzer.
Closes: https://sourceforge.net/p/flac/bugs/421/
Reported-by : Hanno Böck <hanno@hboeck.de>
(from Debian Stretch)
https://www.openwall.com/lists/oss-security/2015/02/14/4
---
src/libFLAC/stream_decoder.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -1739,6 +1739,11 @@
return false; /* read_callback_ sets the state for us */
/* read comments */
+ if (obj->num_comments > 100000) {
+ /* Possibly malicious file. */
+ obj->num_comments = 0;
+ return false;
+ }
if(obj->num_comments > 0) {
if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;