rpms/flac/FC-6 flac-1.1.2-bufferoverflow-fix.diff, NONE, 1.1 flac.spec, 1.22, 1.23
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Wed Oct 17 15:05:05 UTC 2007
Author: bnocera
Update of /cvs/dist/rpms/flac/FC-6
In directory cvs.devel.redhat.com:/tmp/cvs-serv27187
Modified Files:
flac.spec
Added Files:
flac-1.1.2-bufferoverflow-fix.diff
Log Message:
* Wed Oct 17 2007 - Bastien Nocera <bnocera at redhat.com> - 1.1.2-28
- Add patch from Takashi Iwai to fix CVE-2007-4619 (#332581)
flac-1.1.2-bufferoverflow-fix.diff:
include/share/alloc.h | 212 ++++++++++++++++++++++++++++++++++++++
src/libFLAC++/metadata.cpp | 14 +-
src/libFLAC/include/private/md5.h | 2
src/libFLAC/md5.c | 8 +
src/libFLAC/memory.c | 30 ++++-
src/libFLAC/metadata_iterators.c | 18 +--
src/libFLAC/metadata_object.c | 63 +++++++----
src/libFLAC/stream_decoder.c | 32 +++--
src/libFLAC/stream_encoder.c | 3
src/metaflac/operations.c | 5
src/metaflac/options.c | 19 ++-
src/metaflac/utils.c | 5
src/plugin_common/charset.c | 6 +
src/plugin_common/tags.c | 34 +++---
src/plugin_winamp2/in_flac.c | 3
src/plugin_winamp2/infobox.c | 5
src/plugin_xmms/plugin.c | 9 +
src/share/utf8/charset.c | 3
src/share/utf8/iconvert.c | 9 +
src/share/utf8/utf8.c | 44 +++++--
20 files changed, 421 insertions(+), 103 deletions(-)
--- NEW FILE flac-1.1.2-bufferoverflow-fix.diff ---
--- src/metaflac/operations.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/metaflac/operations.c 2007-10-12 15:41:55.000000000 +0200
@@ -21,6 +21,7 @@
#include "utils.h"
#include "FLAC/assert.h"
#include "FLAC/metadata.h"
+#include "share/alloc.h"
#include "share/grabbag.h"
#include <stdio.h>
#include <stdlib.h>
@@ -430,8 +431,8 @@ FLAC__bool do_shorthand_operation__add_r
}
if(
- 0 == (title_gains = (float*)malloc(sizeof(float) * num_files)) ||
- 0 == (title_peaks = (float*)malloc(sizeof(float) * num_files))
+ 0 == (title_gains = (float*)safe_malloc_mul_2op_(sizeof(float), /*times*/num_files)) ||
+ 0 == (title_peaks = (float*)safe_malloc_mul_2op_(sizeof(float), /*times*/num_files))
)
die("out of memory allocating space for title gains/peaks");
--- src/metaflac/options.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/metaflac/options.c 2007-10-12 18:05:01.000000000 +0200
@@ -20,6 +20,7 @@
#include "usage.h"
#include "utils.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -183,7 +184,7 @@ FLAC__bool parse_options(int argc, char
if(options->num_files > 0) {
unsigned i = 0;
- if(0 == (options->filenames = (char**)malloc(sizeof(char*) * options->num_files)))
+ if(0 == (options->filenames = (char**)safe_malloc_mul_2op_(sizeof(char*), /*times*/options->num_files)))
die("out of memory allocating space for file names list");
while(share__optind < argc)
options->filenames[i++] = local_strdup(argv[share__optind++]);
@@ -662,8 +663,10 @@ void append_new_operation(CommandLineOpt
}
if(options->ops.capacity <= options->ops.num_operations) {
unsigned original_capacity = options->ops.capacity;
- options->ops.capacity *= 4;
- if(0 == (options->ops.operations = (Operation*)realloc(options->ops.operations, sizeof(Operation) * options->ops.capacity)))
+ if(options->ops.capacity > SIZE_MAX / 2) /* overflow check */
+ die("out of memory allocating space for option list");
+ options->ops.capacity *= 2;
+ if(0 == (options->ops.operations = (Operation*)safe_realloc_mul_2op_(options->ops.operations, sizeof(Operation), /*times*/options->ops.capacity)))
die("out of memory allocating space for option list");
memset(options->ops.operations + original_capacity, 0, sizeof(Operation) * (options->ops.capacity - original_capacity));
}
@@ -681,8 +684,10 @@ void append_new_argument(CommandLineOpti
}
if(options->args.capacity <= options->args.num_arguments) {
unsigned original_capacity = options->args.capacity;
- options->args.capacity *= 4;
- if(0 == (options->args.arguments = (Argument*)realloc(options->args.arguments, sizeof(Argument) * options->args.capacity)))
+ if(options->args.capacity > SIZE_MAX / 2) /* overflow check */
+ die("out of memory allocating space for option list");
+ options->args.capacity *= 2;
+ if(0 == (options->args.arguments = (Argument*)safe_realloc_mul_2op_(options->args.arguments, sizeof(Argument), /*times*/options->args.capacity)))
die("out of memory allocating space for option list");
memset(options->args.arguments + original_capacity, 0, sizeof(Argument) * (options->args.capacity - original_capacity));
}
@@ -898,7 +903,7 @@ FLAC__bool parse_block_number(const char
/* make space */
FLAC__ASSERT(out->num_entries > 0);
- if(0 == (out->entries = (unsigned*)malloc(sizeof(unsigned) * out->num_entries)))
+ if(0 == (out->entries = (unsigned*)safe_malloc_mul_2op_(sizeof(unsigned), /*times*/out->num_entries)))
die("out of memory allocating space for option list");
/* load 'em up */
@@ -937,7 +942,7 @@ FLAC__bool parse_block_type(const char *
/* make space */
FLAC__ASSERT(out->num_entries > 0);
- if(0 == (out->entries = (Argument_BlockTypeEntry*)malloc(sizeof(Argument_BlockTypeEntry) * out->num_entries)))
+ if(0 == (out->entries = (Argument_BlockTypeEntry*)safe_malloc_mul_2op_(sizeof(Argument_BlockTypeEntry), /*times*/out->num_entries)))
die("out of memory allocating space for option list");
/* load 'em up */
--- src/metaflac/utils.c-dist 2005-01-25 05:17:20.000000000 +0100
+++ src/metaflac/utils.c 2007-10-12 15:41:55.000000000 +0200
@@ -18,6 +18,7 @@
#include "utils.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
#include "share/utf8.h"
#include <ctype.h>
#include <stdarg.h>
@@ -53,7 +54,7 @@ char *local_strdup(const char *source)
void local_strcat(char **dest, const char *source)
{
- unsigned ndest, nsource;
+ size_t ndest, nsource;
FLAC__ASSERT(0 != dest);
FLAC__ASSERT(0 != source);
@@ -64,7 +65,7 @@ void local_strcat(char **dest, const cha
if(nsource == 0)
return;
- *dest = (char*)realloc(*dest, ndest + nsource + 1);
+ *dest = (char*)safe_realloc_add_3op_(*dest, ndest, /*+*/nsource, /*+*/1);
if(0 == *dest)
die("out of memory growing string");
strcpy((*dest)+ndest, source);
--- src/plugin_xmms/plugin.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/plugin_xmms/plugin.c 2007-10-12 15:41:55.000000000 +0200
@@ -425,8 +425,13 @@ void FLAC_XMMS__get_song_info(char *file
if(title) {
if (source_to_decoder_type (filename) == DECODER_FILE) {
static const char *errtitle = "Invalid FLAC File: ";
- *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
- sprintf(*title, "%s\"%s\"", errtitle, filename);
+ if(strlen(errtitle) + 1 + strlen(filename) + 1 + 1 < strlen(filename)) { /* overflow check */
+ *title = NULL;
+ }
+ else {
+ *title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
+ sprintf(*title, "%s\"%s\"", errtitle, filename);
+ }
} else {
*title = NULL;
}
--- src/share/utf8/utf8.c-dist 2002-11-21 09:41:54.000000000 +0100
+++ src/share/utf8/utf8.c 2007-10-12 15:41:55.000000000 +0200
@@ -2,6 +2,8 @@
* Copyright (C) 2001 Peter Harris <peter.harris at hummingbird.com>
* Copyright (C) 2001 Edmund Grimley Evans <edmundo at rano.org>
*
+ * Buffer overflow checking added: Josh Coalson, 9/9/2007
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -28,6 +30,7 @@
#include <config.h>
#endif
+#include "share/alloc.h"
#include "utf8.h"
#include "charset.h"
@@ -43,7 +46,8 @@
static unsigned char *make_utf8_string(const wchar_t *unicode)
{
- int size = 0, index = 0, out_index = 0;
+ size_t size = 0, n;
+ int index = 0, out_index = 0;
unsigned char *out;
unsigned short c;
@@ -51,16 +55,19 @@ static unsigned char *make_utf8_string(c
c = unicode[index++];
while(c) {
if(c < 0x0080) {
- size += 1;
+ n = 1;
} else if(c < 0x0800) {
- size += 2;
+ n = 2;
} else {
- size += 3;
+ n = 3;
}
+ if(size+n < size) /* overflow check */
+ return NULL;
+ size += n;
c = unicode[index++];
- }
+ }
- out = malloc(size + 1);
+ out = safe_malloc_add_2op_(size, /*+*/1);
if (out == NULL)
return NULL;
index = 0;
@@ -87,7 +94,8 @@ static unsigned char *make_utf8_string(c
static wchar_t *make_unicode_string(const unsigned char *utf8)
{
- int size = 0, index = 0, out_index = 0;
+ size_t size = 0;
+ int index = 0, out_index = 0;
wchar_t *out;
unsigned char c;
@@ -101,11 +109,15 @@ static wchar_t *make_unicode_string(cons
} else {
index += 1;
}
- size += 1;
+ if(size + 1 == 0) /* overflow check */
+ return NULL;
+ size++;
c = utf8[index++];
- }
+ }
- out = malloc((size + 1) * sizeof(wchar_t));
+ if(size + 1 == 0) /* overflow check */
+ return NULL;
+ out = safe_malloc_mul_2op_(size+1, /*times*/sizeof(wchar_t));
if (out == NULL)
return NULL;
index = 0;
@@ -147,7 +159,10 @@ int utf8_encode(const char *from, char *
return -1;
}
- unicode = calloc(wchars + 1, sizeof(unsigned short));
+ if(wchars < 0) /* underflow check */
+ return -1;
+
+ unicode = safe_calloc_((size_t)wchars + 1, sizeof(unsigned short));
if(unicode == NULL)
{
fprintf(stderr, "Out of memory processing string to UTF8\n");
@@ -190,6 +205,9 @@ int utf8_decode(const char *from, char *
chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
-1, NULL, 0, NULL, NULL);
+ if(chars < 0) /* underflow check */
+ return -1;
+
if(chars == 0)
{
fprintf(stderr, "Unicode translation error %d\n", GetLastError());
@@ -197,7 +215,7 @@ int utf8_decode(const char *from, char *
return -1;
}
- *to = calloc(chars + 1, sizeof(unsigned char));
+ *to = safe_calloc_((size_t)chars + 1, sizeof(unsigned char));
if(*to == NULL)
{
fprintf(stderr, "Out of memory processing string to local charset\n");
@@ -285,7 +303,7 @@ static int convert_string(const char *fr
if (ret != -1)
return ret;
- s = malloc(fromlen + 1);
+ s = safe_malloc_add_2op_(fromlen, /*+*/1);
if (!s)
return -1;
strcpy(s, from);
--- src/share/utf8/charset.c-dist 2002-12-04 07:41:50.000000000 +0100
+++ src/share/utf8/charset.c 2007-10-12 15:41:55.000000000 +0200
@@ -35,6 +35,7 @@
#include <stdlib.h>
+#include "share/alloc.h"
#include "charset.h"
#include "charmaps.h"
@@ -492,7 +493,7 @@ int charset_convert(const char *fromcode
if (!charset1 || !charset2 )
return -1;
- tobuf = (char *)malloc(fromlen * charset2->max + 1);
+ tobuf = (char *)safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1);
if (!tobuf)
return -2;
--- src/share/utf8/iconvert.c-dist 2002-12-23 19:41:45.000000000 +0100
+++ src/share/utf8/iconvert.c 2007-10-12 15:41:55.000000000 +0200
@@ -27,6 +27,7 @@
#include <iconv.h>
#include <stdlib.h>
#include <string.h>
+#include "share/alloc.h"
/*
* Convert data from one encoding to another. Return:
@@ -79,7 +80,7 @@ int iconvert(const char *fromcode, const
* This is deliberately not a config option as people often
* change their iconv library without rebuilding applications.
*/
- tocode1 = (char *)malloc(strlen(tocode) + 11);
+ tocode1 = (char *)safe_malloc_add_2op_(strlen(tocode), /*+*/11);
if (!tocode1)
goto fail;
@@ -117,6 +118,8 @@ int iconvert(const char *fromcode, const
break;
if (obl < 6) {
/* Enlarge the buffer */
+ if(utflen*2 < utflen) /* overflow check */
+ goto fail;
utflen *= 2;
newbuf = (char *)realloc(utfbuf, utflen);
if (!newbuf)
@@ -143,7 +146,7 @@ int iconvert(const char *fromcode, const
iconv_close(cd1);
return ret;
}
- newbuf = (char *)realloc(utfbuf, (ob - utfbuf) + 1);
+ newbuf = (char *)safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
if (!newbuf)
goto fail;
ob = (ob - utfbuf) + newbuf;
@@ -194,7 +197,7 @@ int iconvert(const char *fromcode, const
outlen += ob - tbuf;
/* Convert from UTF-8 for real */
- outbuf = (char *)malloc(outlen + 1);
+ outbuf = (char *)safe_malloc_add_2op_(outlen, /*+*/1);
if (!outbuf)
goto fail;
ib = utfbuf;
--- src/plugin_winamp2/infobox.c-dist 2005-01-30 16:10:57.000000000 +0100
+++ src/plugin_winamp2/infobox.c 2007-10-12 15:42:00.000000000 +0200
@@ -19,6 +19,7 @@
#include <windows.h>
#include <stdio.h>
#include "FLAC/all.h"
+#include "share/alloc.h"
#include "plugin_common/all.h"
#include "infobox.h"
#include "config.h"
@@ -70,7 +71,7 @@ static void LoadGenres()
hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return;
genresSize = GetFileSize(hFile, 0);
- if (genresSize && (genres = (char*)malloc(genresSize+2)))
+ if (genresSize && (genres = (char*)safe_malloc_add_2op_(genresSize, /*+*/2)))
{
if (!ReadFile(hFile, genres, genresSize, &spam, NULL) || spam!=genresSize)
{
@@ -183,7 +184,7 @@ static wchar_t *AnsiToWide(const char *s
len = strlen(src) + 1;
/* copy */
- dest = (wchar_t*)malloc(len*sizeof(wchar_t));
+ dest = (wchar_t*)safe_malloc_mul_2op_(len, /*times*/sizeof(wchar_t));
if (dest) mbstowcs(dest, src, len);
return dest;
}
--- src/plugin_winamp2/in_flac.c-dist 2005-02-02 05:50:00.000000000 +0100
+++ src/plugin_winamp2/in_flac.c 2007-10-12 15:42:00.000000000 +0200
@@ -19,6 +19,7 @@
#include <windows.h>
#include <stdio.h>
+#include "share/alloc.h"
#include "winamp2/in2.h"
#include "config.h"
#include "infobox.h"
@@ -274,7 +275,7 @@ static T_CHAR *get_tag(const T_CHAR *tag
if (!tag)
return 0;
/* Vorbis comment names must be ASCII, so convert 'tag' first */
- tagname = malloc(wcslen(tag)+1);
+ tagname = safe_malloc_add_2op_(wcslen(tag), /*+*/1);
for(p=tagname;*tag;) {
if(*tag > 0x7d) {
free(tagname);
--- src/libFLAC/md5.c-dist 2004-07-23 03:13:06.000000000 +0200
+++ src/libFLAC/md5.c 2007-10-12 17:26:20.000000000 +0200
@@ -230,7 +230,13 @@ FLAC__MD5Accumulate(struct FLAC__MD5Cont
unsigned channel, sample, a_byte;
FLAC__int32 a_word;
FLAC__byte *buf_;
- const unsigned bytes_needed = channels * samples * bytes_per_sample;
+ const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
+
+ /* overflow check */
+ if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
+ return false;
+ if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
+ return false;
if(ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed);
--- src/libFLAC/metadata_iterators.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/libFLAC/metadata_iterators.c 2007-10-12 17:58:31.000000000 +0200
@@ -48,6 +48,7 @@
#include "FLAC/assert.h"
#include "FLAC/file_decoder.h"
+#include "share/alloc.h"
#ifdef max
#undef max
@@ -1922,6 +1923,9 @@ FLAC__Metadata_SimpleIteratorStatus read
if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+ if(block_length < id_bytes)
+ return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+
block_length -= id_bytes;
if(block_length == 0) {
@@ -1949,7 +1953,7 @@ FLAC__Metadata_SimpleIteratorStatus read
if(block->num_points == 0)
block->points = 0;
- else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint))))
+ else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(block->num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint))))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < block->num_points; i++) {
@@ -1982,7 +1986,7 @@ FLAC__Metadata_SimpleIteratorStatus read
entry->entry = 0;
}
else {
- if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+ if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_2op_(entry->length, /*+*/1)))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
@@ -2013,7 +2017,7 @@ FLAC__Metadata_SimpleIteratorStatus read
if(block->num_comments == 0) {
block->comments = 0;
}
- else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry))))
+ else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_calloc_(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry))))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < block->num_comments; i++) {
@@ -2068,7 +2072,7 @@ FLAC__Metadata_SimpleIteratorStatus read
if(track->num_indices == 0) {
track->indices = 0;
}
- else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index))))
+ else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index))))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < track->num_indices; i++) {
@@ -2128,7 +2132,7 @@ FLAC__Metadata_SimpleIteratorStatus read
if(block->num_tracks == 0) {
block->tracks = 0;
}
- else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track))))
+ else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track))))
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
for(i = 0; i < block->num_tracks; i++) {
@@ -2812,7 +2816,7 @@ FLAC__bool open_tempfile_(const char *fi
{
static const char *tempfile_suffix = ".metadata_edit";
if(0 == tempfile_path_prefix) {
- if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
+ if(0 == (*tempfilename = (char*)safe_malloc_add_3op_(strlen(filename), /*+*/strlen(tempfile_suffix), /*+*/1))) {
*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -2826,7 +2830,7 @@ FLAC__bool open_tempfile_(const char *fi
else
p++;
- if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) {
+ if(0 == (*tempfilename = (char*)safe_malloc_add_4op_(strlen(tempfile_path_prefix), /*+*/strlen(p), /*+*/strlen(tempfile_suffix), /*+*/2))) {
*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
return false;
}
--- src/libFLAC/metadata_object.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/libFLAC/metadata_object.c 2007-10-12 17:34:40.000000000 +0200
@@ -35,6 +35,7 @@
#include "private/metadata.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
/****************************************************************************
@@ -47,7 +48,7 @@ static FLAC__bool copy_bytes_(FLAC__byte
{
if(bytes > 0 && 0 != from) {
FLAC__byte *x;
- if(0 == (x = (FLAC__byte*)malloc(bytes)))
+ if(0 == (x = (FLAC__byte*)safe_malloc_(bytes)))
return false;
memcpy(x, from, bytes);
*to = x;
@@ -62,7 +63,7 @@ static FLAC__bool copy_bytes_(FLAC__byte
static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length)
{
- FLAC__byte *x = (FLAC__byte*)realloc(*entry, length+1);
+ FLAC__byte *x = (FLAC__byte*)safe_realloc_add_2op_(*entry, length, /*+*/1);
if(0 != x) {
x[length] = '\0';
*entry = x;
@@ -82,7 +83,7 @@ static FLAC__bool copy_vcentry_(FLAC__St
else {
FLAC__byte *x;
FLAC__ASSERT(from->length > 0);
- if(0 == (x = (FLAC__byte*)malloc(from->length+1)))
+ if(0 == (x = (FLAC__byte*)safe_malloc_add_2op_(from->length, /*+*/1)))
return false;
memcpy(x, from->entry, from->length);
x[from->length] = '\0';
@@ -100,7 +101,7 @@ static FLAC__bool copy_track_(FLAC__Stre
else {
FLAC__StreamMetadata_CueSheet_Index *x;
FLAC__ASSERT(from->num_indices > 0);
- if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)malloc(from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index))))
+ if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)safe_malloc_mul_2op_(from->num_indices, /*times*/sizeof(FLAC__StreamMetadata_CueSheet_Index))))
return false;
memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
to->indices = x;
@@ -122,7 +123,7 @@ static FLAC__StreamMetadata_SeekPoint *s
FLAC__ASSERT(num_points > 0);
- object_array = (FLAC__StreamMetadata_SeekPoint*)malloc(num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
+ object_array = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint));
if(0 != object_array) {
unsigned i;
@@ -155,7 +156,7 @@ static FLAC__StreamMetadata_VorbisCommen
{
FLAC__ASSERT(num_comments > 0);
- return (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
+ return (FLAC__StreamMetadata_VorbisComment_Entry*)safe_calloc_(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
}
static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments)
@@ -294,14 +295,14 @@ static FLAC__StreamMetadata_CueSheet_Ind
{
FLAC__ASSERT(num_indices > 0);
- return (FLAC__StreamMetadata_CueSheet_Index*)calloc(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
+ return (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
}
static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks)
{
FLAC__ASSERT(num_tracks > 0);
- return (FLAC__StreamMetadata_CueSheet_Track*)calloc(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
+ return (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
}
static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks)
@@ -454,6 +455,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__met
case FLAC__METADATA_TYPE_PADDING:
break;
case FLAC__METADATA_TYPE_APPLICATION:
+ if(to->length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */
+ FLAC__metadata_object_delete(to);
+ return 0;
+ }
memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8);
if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) {
FLAC__metadata_object_delete(to);
@@ -462,6 +467,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__met
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
to->data.seek_table.num_points = object->data.seek_table.num_points;
+ if(to->data.seek_table.num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) { /* overflow check */
+ FLAC__metadata_object_delete(to);
+ return 0;
+ }
if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) {
FLAC__metadata_object_delete(to);
return 0;
@@ -788,8 +797,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
return false;
}
else {
- const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
- const unsigned new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+ const size_t old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+ const size_t new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+
+ /* overflow check */
+ if((size_t)new_num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint))
+ return false;
FLAC__ASSERT(object->data.seek_table.num_points > 0);
@@ -982,8 +995,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
return false;
}
else {
- const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
- const unsigned new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+ const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+ const size_t new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+
+ /* overflow check */
+ if((size_t)new_num_comments > SIZE_MAX / sizeof(FLAC__StreamMetadata_VorbisComment_Entry))
+ return false;
FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0);
@@ -1131,7 +1148,7 @@ FLAC_API FLAC__bool FLAC__metadata_objec
const size_t nn = strlen(field_name);
const size_t nv = strlen(field_value);
entry->length = nn + 1 /*=*/ + nv;
- if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+ if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_4op_(nn, /*+*/1, /*+*/nv, /*+*/1)))
return false;
memcpy(entry->entry, field_name, nn);
entry->entry[nn] = '=';
@@ -1158,9 +1175,9 @@ FLAC_API FLAC__bool FLAC__metadata_objec
FLAC__ASSERT(0 != eq);
if(0 == eq)
return false; /* double protection */
- if(0 == (*field_name = (char*)malloc(nn+1)))
+ if(0 == (*field_name = (char*)safe_malloc_add_2op_(nn, /*+*/1)))
return false;
- if(0 == (*field_value = (char*)malloc(nv+1))) {
+ if(0 == (*field_value = (char*)safe_malloc_add_2op_(nv, /*+*/1))) {
free(*field_name);
return false;
}
@@ -1290,8 +1307,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
return false;
}
else {
- const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
- const unsigned new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+ const size_t old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+ const size_t new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+
+ /* overflow check */
+ if((size_t)new_num_indices > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Index))
+ return false;
FLAC__ASSERT(track->num_indices > 0);
@@ -1374,8 +1395,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
return false;
}
else {
- const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
- const unsigned new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+ const size_t old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+ const size_t new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+
+ /* overflow check */
+ if((size_t)new_num_tracks > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Track))
+ return false;
FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0);
--- src/libFLAC/stream_encoder.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/libFLAC/stream_encoder.c 2007-10-12 17:34:10.000000000 +0200
@@ -35,6 +35,7 @@
#include <string.h> /* for memcpy() */
#include "FLAC/assert.h"
#include "FLAC/stream_decoder.h"
+#include "share/alloc.h"
#include "protected/stream_encoder.h"
#include "private/bitbuffer.h"
#include "private/bitmath.h"
@@ -836,7 +837,7 @@ FLAC_API FLAC__StreamEncoderState FLAC__
*/
encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize;
for(i = 0; i < encoder->protected_->channels; i++) {
- if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder->private_->verify.input_fifo.size)))
+ if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), encoder->private_->verify.input_fifo.size)))
return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
}
encoder->private_->verify.input_fifo.tail = 0;
--- src/libFLAC/stream_decoder.c-dist 2007-10-12 15:41:37.000000000 +0200
+++ src/libFLAC/stream_decoder.c 2007-10-12 17:33:29.000000000 +0200
@@ -33,6 +33,7 @@
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memset/memcpy() */
#include "FLAC/assert.h"
+#include "share/alloc.h"
#include "protected/stream_decoder.h"
#include "private/bitbuffer.h"
#include "private/bitmath.h"
@@ -128,7 +129,7 @@ typedef struct FLAC__StreamDecoderPrivat
FLAC__StreamMetadata seek_table;
FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
FLAC__byte *metadata_filter_ids;
- unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
+ size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
FLAC__Frame frame;
FLAC__bool cached; /* true if there is a byte in lookahead */
FLAC__CPUInfo cpuinfo;
@@ -214,7 +215,7 @@ FLAC_API FLAC__StreamDecoder *FLAC__stre
}
decoder->private_->metadata_filter_ids_capacity = 16;
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
+ if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_malloc_mul_2op_((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), decoder->private_->metadata_filter_ids_capacity))) {
FLAC__bitbuffer_delete(decoder->private_->input);
free(decoder->private_);
free(decoder->protected_);
@@ -455,7 +456,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
+ if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2)))
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
decoder->private_->metadata_filter_ids_capacity *= 2;
}
@@ -512,7 +513,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder
FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
- if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2)))
+ if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2)))
return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
decoder->private_->metadata_filter_ids_capacity *= 2;
}
@@ -804,7 +805,7 @@ FLAC__bool allocate_output_(FLAC__Stream
* (at negative indices) for alignment purposes; we use 4
* to keep the data well-aligned.
*/
- tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
+ tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
if(tmp == 0) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
@@ -829,7 +830,7 @@ FLAC__bool allocate_output_(FLAC__Stream
FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
{
- unsigned i;
+ size_t i;
FLAC__ASSERT(0 != decoder);
FLAC__ASSERT(0 != decoder->private_);
@@ -947,6 +948,11 @@ FLAC__bool read_metadata_(FLAC__StreamDe
if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
+ if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
+ decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
+ return false;
+ }
+
real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
@@ -1004,7 +1010,7 @@ FLAC__bool read_metadata_(FLAC__StreamDe
}
decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
- /* now we have to free any malloc'ed data in the block */
+ /* now we have to free any malloc()ed data in the block */
switch(type) {
case FLAC__METADATA_TYPE_PADDING:
break;
@@ -1132,7 +1138,7 @@ FLAC__bool read_metadata_seektable_(FLAC
decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
/* use realloc since we may pass through here several times (e.g. after seeking) */
- if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) {
+ if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1171,7 +1177,7 @@ FLAC__bool read_metadata_vorbiscomment_(
if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
if(obj->vendor_string.length > 0) {
- if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) {
+ if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1189,7 +1195,7 @@ FLAC__bool read_metadata_vorbiscomment_(
/* read comments */
if(obj->num_comments > 0) {
- if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
+ 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;
return false;
}
@@ -1198,7 +1204,7 @@ FLAC__bool read_metadata_vorbiscomment_(
if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->comments[i].length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
if(obj->comments[i].length > 0) {
- if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) {
+ if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1244,7 +1250,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC_
obj->num_tracks = x;
if(obj->num_tracks > 0) {
- if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
+ if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
@@ -1277,7 +1283,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC_
track->num_indices = (FLAC__byte)x;
if(track->num_indices > 0) {
- if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
+ if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
--- src/libFLAC/memory.c-dist 2005-01-25 05:14:49.000000000 +0100
+++ src/libFLAC/memory.c 2007-10-12 17:27:42.000000000 +0200
@@ -31,6 +31,7 @@
#include "private/memory.h"
#include "FLAC/assert.h"
+#include "share/alloc.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -44,10 +45,10 @@ void *FLAC__memory_alloc_aligned(size_t
#ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */
- x = malloc(bytes+31);
+ x = safe_malloc_add_2op_(bytes, /*+*/31);
*aligned_address = (void*)(((unsigned)x + 31) & -32);
#else
- x = malloc(bytes);
+ x = safe_malloc_(bytes);
*aligned_address = x;
#endif
return x;
@@ -66,7 +67,10 @@ FLAC__bool FLAC__memory_alloc_aligned_in
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -92,7 +96,10 @@ FLAC__bool FLAC__memory_alloc_aligned_ui
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -118,7 +125,10 @@ FLAC__bool FLAC__memory_alloc_aligned_ui
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -144,7 +154,10 @@ FLAC__bool FLAC__memory_alloc_aligned_un
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
@@ -172,7 +185,10 @@ FLAC__bool FLAC__memory_alloc_aligned_re
FLAC__ASSERT(0 != aligned_pointer);
FLAC__ASSERT(unaligned_pointer != aligned_pointer);
- pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv);
+ if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+ return false;
+
+ pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
if(0 == pu) {
return false;
}
--- src/libFLAC/include/private/md5.h-dist 2004-07-23 03:23:14.000000000 +0200
+++ src/libFLAC/include/private/md5.h 2007-10-12 17:39:03.000000000 +0200
@@ -41,7 +41,7 @@ struct FLAC__MD5Context {
FLAC__uint32 bytes[2];
FLAC__uint32 in[16];
FLAC__byte *internal_buf;
- unsigned capacity;
+ size_t capacity;
};
FLAC_API void FLAC__MD5Init(struct FLAC__MD5Context *context);
--- src/plugin_common/charset.c-dist 2005-01-25 05:20:28.000000000 +0100
+++ src/plugin_common/charset.c 2007-10-12 15:42:02.000000000 +0200
@@ -83,6 +83,8 @@ char* FLAC_plugin__charset_convert_strin
/* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
/* + 1 for nul in case len == 1 */
outsize = ((length + 3) & ~3) + 1;
+ if(outsize < length) /* overflow check */
+ return NULL;
out = (char*)malloc(outsize);
outleft = outsize - 1;
outptr = out;
@@ -95,6 +97,10 @@ retry:
{
case E2BIG:
used = outptr - out;
+ if((outsize - 1) * 2 + 1 <= outsize) { /* overflow check */
+ free(out);
+ return NULL;
+ }
outsize = (outsize - 1) * 2 + 1;
out = realloc(out, outsize);
outptr = out + used;
--- src/plugin_common/tags.c-dist 2005-02-01 06:12:30.000000000 +0100
+++ src/plugin_common/tags.c 2007-10-12 17:41:23.000000000 +0200
@@ -25,15 +25,15 @@
#include "FLAC/metadata.h"
-static __inline unsigned local__wide_strlen(const FLAC__uint16 *s)
+static __inline size_t local__wide_strlen(const FLAC__uint16 *s)
{
- unsigned n = 0;
+ size_t n = 0;
while(*s++)
n++;
return n;
}
-static __inline unsigned local__utf8len(const FLAC__byte *utf8)
+static __inline size_t local__utf8len(const FLAC__byte *utf8)
{
FLAC__ASSERT(0 != utf8);
if ((utf8[0] & 0x80) == 0)
@@ -46,9 +46,9 @@ static __inline unsigned local__utf8len(
return 0;
}
-static __inline unsigned local__utf8_to_ucs2(const FLAC__byte *utf8, FLAC__uint16 *ucs2)
+static __inline size_t local__utf8_to_ucs2(const FLAC__byte *utf8, FLAC__uint16 *ucs2)
{
- const unsigned len = local__utf8len(utf8);
+ const size_t len = local__utf8len(utf8);
FLAC__ASSERT(0 != ucs2);
@@ -65,7 +65,7 @@ static __inline unsigned local__utf8_to_
static FLAC__uint16 *local__convert_utf8_to_ucs2(const char *src, unsigned length)
{
FLAC__uint16 *out;
- unsigned chars = 0;
+ size_t chars = 0;
FLAC__ASSERT(0 != src);
@@ -73,7 +73,7 @@ static FLAC__uint16 *local__convert_utf8
{
const char *s, *end;
for (s=src, end=src+length; s<end; chars++) {
- const unsigned n = local__utf8len(s);
+ const size_t n = local__utf8len(s);
if (n == 0)
return 0;
s += n;
@@ -82,7 +82,7 @@ static FLAC__uint16 *local__convert_utf8
}
/* allocate */
- out = (FLAC__uint16*)malloc(chars * sizeof(FLAC__uint16));
+ out = (FLAC__uint16*)safe_malloc_mul_2op_(chars, /*times*/sizeof(FLAC__uint16));
if (0 == out) {
FLAC__ASSERT(0);
return 0;
@@ -98,7 +98,7 @@ static FLAC__uint16 *local__convert_utf8
return out;
}
-static __inline unsigned local__ucs2len(FLAC__uint16 ucs2)
+static __inline size_t local__ucs2len(FLAC__uint16 ucs2)
{
if (ucs2 < 0x0080)
return 1;
@@ -108,7 +108,7 @@ static __inline unsigned local__ucs2len(
return 3;
}
-static __inline unsigned local__ucs2_to_utf8(FLAC__uint16 ucs2, FLAC__byte *utf8)
+static __inline size_t local__ucs2_to_utf8(FLAC__uint16 ucs2, FLAC__byte *utf8)
{
if (ucs2 < 0x080) {
utf8[0] = (FLAC__byte)ucs2;
@@ -130,19 +130,23 @@ static __inline unsigned local__ucs2_to_
static char *local__convert_ucs2_to_utf8(const FLAC__uint16 *src, unsigned length)
{
char *out;
- unsigned len = 0;
+ size_t len = 0, n;
FLAC__ASSERT(0 != src);
/* calculate length */
{
unsigned i;
- for (i = 0; i < length; i++)
- len += local__ucs2len(src[i]);
+ for (i = 0; i < length; i++) {
+ n = local__ucs2len(src[i]);
+ if(len + n < len) /* overflow check */
+ return 0;
+ len += n;
+ }
}
/* allocate */
- out = (char*)malloc(len * sizeof(char));
+ out = (char*)safe_malloc_mul_2op_(len, /*times*/sizeof(char));
if (0 == out)
return 0;
@@ -265,7 +269,7 @@ FLAC__bool FLAC_plugin__tags_add_tag_utf
const size_t value_len = strlen(value);
const size_t separator_len = strlen(separator);
FLAC__byte *new_entry;
- if(0 == (new_entry = (FLAC__byte*)realloc(entry->entry, entry->length + value_len + separator_len + 1)))
+ if(0 == (new_entry = (FLAC__byte*)safe_realloc_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;
--- src/libFLAC++/metadata.cpp-dist 2005-01-25 05:15:48.000000000 +0100
+++ src/libFLAC++/metadata.cpp 2007-10-12 17:42:02.000000000 +0200
@@ -29,6 +29,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define __STDC_LIMIT_MACROS 1 /* otherwise SIZE_MAX is not defined for c++ */
+#include "share/alloc.h"
#include "FLAC++/metadata.h"
#include "FLAC/assert.h"
#include <stdlib.h> // for malloc(), free()
@@ -568,7 +570,7 @@
clear_entry();
- if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length+1))) {
+ if(0 == (entry_.entry = (FLAC__byte*)safe_malloc_add_2op_(field_length, /*+*/1))) {
is_valid_ = false;
}
else {
@@ -617,7 +619,7 @@
clear_field_value();
- if(0 == (field_value_ = (char *)malloc(field_value_length+1))) {
+ if(0 == (field_value_ = (char *)safe_malloc_add_2op_(field_value_length, /*+*/1))) {
is_valid_ = false;
}
else {
@@ -707,7 +709,7 @@
{
clear_entry();
- if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_ + 1))) {
+ if(0 == (entry_.entry = (FLAC__byte*)safe_malloc_add_4op_(field_name_length_, /*+*/1, /*+*/field_value_length_, /*+*/1))) {
is_valid_ = false;
}
else {
@@ -733,7 +735,7 @@
p = (const char *)entry_.entry + entry_.length;
field_name_length_ = p - (const char *)entry_.entry;
- if(0 == (field_name_ = (char *)malloc(field_name_length_ + 1))) { // +1 for the trailing \0
+ if(0 == (field_name_ = (char *)safe_malloc_add_2op_(field_name_length_, /*+*/1))) { // +1 for the trailing \0
is_valid_ = false;
return;
}
@@ -742,14 +744,14 @@
if(entry_.length - field_name_length_ == 0) {
field_value_length_ = 0;
- if(0 == (field_value_ = (char *)malloc(0))) {
+ if(0 == (field_value_ = (char *)safe_malloc_(0))) {
is_valid_ = false;
return;
}
}
else {
field_value_length_ = entry_.length - field_name_length_ - 1;
- if(0 == (field_value_ = (char *)malloc(field_value_length_ + 1))) { // +1 for the trailing \0
+ if(0 == (field_value_ = (char *)safe_malloc_add_2op_(field_value_length_, /*+*/1))) { // +1 for the trailing \0
is_valid_ = false;
return;
}
--- include/share/alloc.h-dist 2007-10-12 15:42:02.000000000 +0200
+++ include/share/alloc.h 2007-10-12 15:42:02.000000000 +0200
@@ -0,0 +1,212 @@
+/* alloc - Convenience routines for safely allocating memory
+ * Copyright (C) 2007 Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FLAC__SHARE__ALLOC_H
+#define FLAC__SHARE__ALLOC_H
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
+ * before #including this file, otherwise SIZE_MAX might not be defined
+ */
+
+#include <limits.h> /* for SIZE_MAX */
+#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
+#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
+#endif
+#include <stdlib.h> /* for size_t, malloc(), etc */
+
+#ifndef SIZE_MAX
+# ifndef SIZE_T_MAX
+# ifdef _MSC_VER
+# define SIZE_T_MAX UINT_MAX
+# else
+# error
+# endif
+# endif
+# define SIZE_MAX SIZE_T_MAX
+#endif
+
+#ifndef FLaC__INLINE
+#define FLaC__INLINE
+#endif
+
+/* avoid malloc()ing 0 bytes, see:
+ * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
+*/
+static FLaC__INLINE void *safe_malloc_(size_t size)
+{
+ /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ if(!size)
+ size++;
+ return malloc(size);
+}
+
+static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size)
+{
+ if(!nmemb || !size)
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ return calloc(nmemb, size);
+}
+
+/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
+
+static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ return safe_malloc_(size2);
+}
+
+static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ return safe_malloc_(size3);
+}
+
+static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ size4 += size3;
+ if(size4 < size3)
+ return 0;
+ return safe_malloc_(size4);
+}
+
+static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2)
+#if 0
+needs support for cases where sizeof(size_t) != 4
+{
+ /* could be faster #ifdef'ing off SIZEOF_SIZE_T */
+ if(sizeof(size_t) == 4) {
+ if ((double)size1 * (double)size2 < 4294967296.0)
+ return malloc(size1*size2);
+ }
+ return 0;
+}
+#else
+/* better? */
+{
+ if(!size1 || !size2)
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ return malloc(size1*size2);
+}
+#endif
+
+static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || !size2 || !size3)
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ size1 *= size2;
+ if(size1 > SIZE_MAX / size3)
+ return 0;
+ return malloc(size1*size3);
+}
+
+/* size1*size2 + size3 */
+static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || !size2)
+ return safe_malloc_(size3);
+ if(size1 > SIZE_MAX / size2)
+ return 0;
+ return safe_malloc_add_2op_(size1*size2, size3);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
+{
+ if(!size1 || (!size2 && !size3))
+ return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+ size2 += size3;
+ if(size2 < size3)
+ return 0;
+ return safe_malloc_mul_2op_(size1, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ return realloc(ptr, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ return realloc(ptr, size3);
+}
+
+static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
+{
+ size2 += size1;
+ if(size2 < size1)
+ return 0;
+ size3 += size2;
+ if(size3 < size2)
+ return 0;
+ size4 += size3;
+ if(size4 < size3)
+ return 0;
+ return realloc(ptr, size4);
+}
+
+static FLaC__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)
+ return 0;
+ return realloc(ptr, size1*size2);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_realloc_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_mul_2op_(ptr, size1, size2);
+}
+
+#endif
Index: flac.spec
===================================================================
RCS file: /cvs/dist/rpms/flac/FC-6/flac.spec,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- flac.spec 12 Jul 2006 21:56:40 -0000 1.22
+++ flac.spec 17 Oct 2007 15:05:03 -0000 1.23
@@ -1,13 +1,14 @@
Summary: An encoder/decoder for the Free Lossless Audio Codec.
Name: flac
Version: 1.1.2
-Release: 27
+Release: 28
License: LGPL/GPL
Group: Applications/Multimedia
Source: http://prdownloads.sourceforge.net/flac/flac-%{version}.tar.gz
Patch1: flac-1.1.2-libtool.patch
Patch3: flac-1.1.0-gnu-stack.patch
Patch4: flac-1.1.2-noxmms.patch
+Patch5: flac-1.1.2-bufferoverflow-fix.diff
URL: http://flac.sourceforge.net/
BuildRoot: %{_tmppath}/%{name}-root
BuildRequires: glib2-devel, libogg-devel, doxygen, nasm
@@ -37,6 +38,7 @@
%patch1 -p1 -b .libtool
%patch3 -p1 -b .gnu-stack
%patch4 -p1 -b .noxmms
+%patch5 -p0 -b .CVE-2007-4619
autoreconf -i -f
@@ -76,6 +78,9 @@
%{_datadir}/aclocal/*.m4
%changelog
+* Wed Oct 17 2007 - Bastien Nocera <bnocera at redhat.com> - 1.1.2-28
+- Add patch from Takashi Iwai to fix CVE-2007-4619 (#332581)
+
* Wed Jul 12 2006 Jesse Keating <jkeating at redhat.com> - 1.1.2-27
- rebuild
- Try building w/ glib2-devel
More information about the fedora-cvs-commits
mailing list