Fix potential integer overflows in memory allocation.

Patch by Rich and me


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@18559 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
rtogni 2006-06-04 22:41:27 +00:00
parent b4ddc383ef
commit 9da9317579
22 changed files with 86 additions and 46 deletions

View File

@ -194,6 +194,8 @@ static int asf_streaming_parse_header(int fd, streaming_ctrl_t* streaming_ctrl)
return -1;
}
// audit: do not overflow buffer_size
if (size > SIZE_MAX - buffer_size) return -1;
buffer = (char*) malloc(size+buffer_size);
if(buffer == NULL) {
mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MPDEMUX_ASF_BufferMallocFailed,size+buffer_size);

View File

@ -211,7 +211,7 @@ while(1){
break;
}
priv->suidx_size++;
priv->suidx = realloc(priv->suidx, priv->suidx_size * sizeof (avisuperindex_chunk));
priv->suidx = realloc_struct(priv->suidx, priv->suidx_size, sizeof (avisuperindex_chunk));
s = &priv->suidx[priv->suidx_size-1];
chunksize-=24;

View File

@ -12,6 +12,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <inttypes.h>
#include "cookies.h"
#include "http.h"
@ -110,6 +111,11 @@ static char *load_file(const char *filename, off_t * length)
return NULL;
}
if (*length > SIZE_MAX - 1) {
mp_msg(MSGT_NETWORK, MSGL_V, "File too big, could not malloc.");
return NULL;
}
lseek(fd, SEEK_SET, 0);
if (!(buffer = malloc(*length + 1))) {

View File

@ -377,7 +377,7 @@ static demuxer_t* demux_open_film(demuxer_t* demuxer)
// allocate enough entries for the chunk
film_data->chunks =
(film_chunk_t *)malloc(film_data->total_chunks * sizeof(film_chunk_t));
(film_chunk_t *)calloc(film_data->total_chunks, sizeof(film_chunk_t));
// build the chunk index
counting_chunks = 1;

View File

@ -103,6 +103,7 @@ static demuxer_t* demux_open_fli(demuxer_t* demuxer){
frames->current_frame = 0;
// allocate enough entries for the indices
// audit: num_frames is 16bit so it is safe against overflow
frames->filepos = (off_t *)malloc(frames->num_frames * sizeof(off_t));
frames->frame_size = (int *)malloc(frames->num_frames * sizeof(int));

View File

@ -11,6 +11,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
#include "stream.h"
#include "demuxer.h"
@ -1083,6 +1084,8 @@ demux_mkv_read_trackentry (demuxer_t *demuxer)
{
int x;
uint64_t num = ebml_read_length (s, &x);
// audit: cheap guard against overflows later..
if (num > SIZE_MAX - 1000) return 0;
l = x + num;
track->private_data = malloc (num);
if (stream_read(s, track->private_data, num) != (int) num)

View File

@ -145,16 +145,6 @@ typedef struct {
void* desc; // image/sound/etc description (pointer to ImageDescription etc)
} mov_track_t;
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
void *realloc_struct(void *ptr, size_t nmemb, size_t size) {
if (nmemb > SIZE_MAX / size)
return NULL;
return realloc(ptr, nmemb * size);
}
void mov_build_index(mov_track_t* trak,int timescale){
int i,j,s;
int last=trak->chunks_size;
@ -166,6 +156,7 @@ void mov_build_index(mov_track_t* trak,int timescale){
mp_msg(MSGT_DEMUX, MSGL_WARN, "No chunk offset table, trying to build one!\n");
trak->chunks_size = trak->samples_size; /* XXX: FIXME ! */
// audit: this code will be vulnerable if it is reenabled (currently #if 0)
trak->chunks = realloc(trak->chunks, sizeof(mov_chunk_t)*trak->chunks_size);
for (i=0; i < trak->chunks_size; i++)
@ -1278,7 +1269,7 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
z_stream zstrm;
stream_t* backup;
if (moov_sz > 0xffffffff - 16) {
if (moov_sz > SIZE_MAX - 16) {
mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid cmvd atom size %d\n", moov_sz);
break;
}

View File

@ -8,7 +8,7 @@
#include <string.h>
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <inttypes.h>
#include "mp_msg.h"
#include "help_mp.h"

View File

@ -235,13 +235,6 @@ typedef struct {
#define IS_AUDIO(x) (((x) == AUDIO_MP2) || ((x) == AUDIO_A52) || ((x) == AUDIO_LPCM_BE) || ((x) == AUDIO_AAC))
#define IS_VIDEO(x) (((x) == VIDEO_MPEG1) || ((x) == VIDEO_MPEG2) || ((x) == VIDEO_MPEG4) || ((x) == VIDEO_H264) || ((x) == VIDEO_AVC))
static void *realloc_struct(void *ptr, size_t nmemb, size_t size)
{
if (nmemb > SIZE_MAX / size)
return NULL;
return realloc(ptr, nmemb * size);
}
static int ts_parse(demuxer_t *demuxer, ES_stream_t *es, unsigned char *packet, int probe);
static uint8_t get_packet_size(const unsigned char *buf, int size)

View File

@ -387,6 +387,8 @@ static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
} else {
// append data to it!
demux_packet_t* dp=ds->asf_packet;
if(dp->len + len + FF_INPUT_BUFFER_PADDING_SIZE < 0)
return 0;
dp->buffer=realloc(dp->buffer,dp->len+len+FF_INPUT_BUFFER_PADDING_SIZE);
memset(dp->buffer+dp->len+len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
//memcpy(dp->buffer+dp->len,data,len);

View File

@ -238,6 +238,18 @@ inline static void free_demux_packet(demux_packet_t* dp){
free(dp);
}
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
static void *realloc_struct(void *ptr, size_t nmemb, size_t size) {
if (nmemb > SIZE_MAX / size) {
free(ptr);
return NULL;
}
return realloc(ptr, nmemb * size);
}
demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id);
demuxer_t* new_demuxer(stream_t *stream,int type,int a_id,int v_id,int s_id,char *filename);
void free_demuxer_stream(demux_stream_t *ds);

View File

@ -221,6 +221,8 @@ ebml_read_ascii (stream_t *s, uint64_t *length)
len = ebml_read_length (s, &l);
if (len == EBML_UINT_INVALID)
return NULL;
if (len > SIZE_MAX - 1)
return NULL;
if (length)
*length = len + l;

View File

@ -315,6 +315,10 @@ int
http_response_append( HTTP_header_t *http_hdr, char *response, int length ) {
if( http_hdr==NULL || response==NULL || length<0 ) return -1;
if( (unsigned)length > SIZE_MAX - http_hdr->buffer_size - 1) {
mp_msg(MSGT_NETWORK,MSGL_FATAL,"Bad size in memory (re)allocation\n");
return -1;
}
http_hdr->buffer = (char*)realloc( http_hdr->buffer, http_hdr->buffer_size+length+1 );
if( http_hdr->buffer==NULL ) {
mp_msg(MSGT_NETWORK,MSGL_FATAL,"Memory (re)allocation failed\n");
@ -340,7 +344,8 @@ int
http_response_parse( HTTP_header_t *http_hdr ) {
char *hdr_ptr, *ptr;
char *field=NULL;
int pos_hdr_sep, hdr_sep_len, len;
int pos_hdr_sep, hdr_sep_len;
size_t len;
if( http_hdr==NULL ) return -1;
if( http_hdr->is_parsed ) return 0;

View File

@ -106,7 +106,7 @@ mf_t* open_mf(char * filename){
{ free( mf ); free( fname ); return NULL; }
mf->nr_of_files=gg.gl_pathc;
mf->names=malloc( gg.gl_pathc * sizeof( char* ) );
mf->names=calloc( gg.gl_pathc, sizeof( char* ) );
mp_msg( MSGT_STREAM,MSGL_INFO,"[mf] number of files: %d (%d)\n",mf->nr_of_files, gg.gl_pathc * sizeof( char* ) );

View File

@ -68,7 +68,7 @@ void muxer_write_chunk(muxer_stream_t *s, size_t len, unsigned int flags, double
int num = s->muxer->muxbuf_num++;
muxbuf_t *buf, *tmp;
tmp = realloc(s->muxer->muxbuf, (num+1) * sizeof(muxbuf_t));
tmp = realloc_struct(s->muxer->muxbuf, (num+1), sizeof(muxbuf_t));
if(!tmp) {
mp_msg(MSGT_MUXER, MSGL_FATAL, MSGTR_MuxbufReallocErr);
return;

View File

@ -109,9 +109,9 @@ static muxer_stream_t* avifile_new_stream(muxer_t *muxer,int type){
s->priv=si=malloc(sizeof(struct avi_stream_info));
memset(si,0,sizeof(struct avi_stream_info));
si->idxsize=256;
si->idx=malloc(sizeof(struct avi_odmlidx_entry)*si->idxsize);
si->idx=calloc(si->idxsize, sizeof(struct avi_odmlidx_entry));
si->riffofssize=16;
si->riffofs=malloc(sizeof(off_t)*(si->riffofssize+1));
si->riffofs=calloc((si->riffofssize+1), sizeof(off_t));
memset(si->riffofs, 0, sizeof(off_t)*si->riffofssize);
switch(type){
@ -174,7 +174,7 @@ static void avifile_odml_new_riff(muxer_t *muxer)
vsi->riffofspos++;
if (vsi->riffofspos>=vsi->riffofssize) {
vsi->riffofssize+=16;
vsi->riffofs=realloc(vsi->riffofs,sizeof(off_t)*(vsi->riffofssize+1));
vsi->riffofs=realloc_struct(vsi->riffofs,(vsi->riffofssize+1),sizeof(off_t));
}
vsi->riffofs[vsi->riffofspos] = ftello(f);
@ -220,7 +220,7 @@ static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags,
// add to the traditional index:
if(muxer->idx_pos>=muxer->idx_size){
muxer->idx_size+=256; // 4kB
muxer->idx=realloc(muxer->idx,16*muxer->idx_size);
muxer->idx=realloc_struct(muxer->idx,muxer->idx_size,16);
}
muxer->idx[muxer->idx_pos].ckid=s->ckid;
muxer->idx[muxer->idx_pos].dwFlags=flags; // keyframe?
@ -232,7 +232,7 @@ static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags,
// add to odml index
if(si->idxpos>=si->idxsize){
si->idxsize+=256;
si->idx=realloc(si->idx,sizeof(*si->idx)*si->idxsize);
si->idx=realloc_struct(si->idx,si->idxsize,sizeof(*si->idx));
}
si->idx[si->idxpos].flags=(flags&AVIIF_KEYFRAME)?0:ODML_NOTKEYFRAME;
si->idx[si->idxpos].ofs=muxer->file_end;
@ -599,7 +599,7 @@ static void avifile_odml_write_index(muxer_t *muxer){
i, entries_per_subidx, si->superidxpos);
si->superidxsize = si->superidxpos;
si->superidx = malloc(sizeof(*si->superidx) * si->superidxsize);
si->superidx = calloc(si->superidxsize, sizeof(*si->superidx));
memset(si->superidx, 0, sizeof(*si->superidx) * si->superidxsize);
idxpos = 0;

View File

@ -1976,6 +1976,8 @@ static int fill_last_frame(muxer_headers_t *spriv, uint8_t *ptr, int len)
if(spriv->framebuf[idx].alloc_size < spriv->framebuf[idx].size + len)
{
if(spriv->framebuf[idx].size > SIZE_MAX - (size_t)len)
return 0;
spriv->framebuf[idx].buffer = (uint8_t*) realloc(spriv->framebuf[idx].buffer, spriv->framebuf[idx].size + len);
if(! spriv->framebuf[idx].buffer)
return 0;
@ -1995,7 +1997,7 @@ static int add_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr, int le
idx = spriv->framebuf_used;
if(idx >= spriv->framebuf_cnt)
{
spriv->framebuf = (mpeg_frame_t*) realloc(spriv->framebuf, (spriv->framebuf_cnt+1)*sizeof(mpeg_frame_t));
spriv->framebuf = (mpeg_frame_t*) realloc_struct(spriv->framebuf, (spriv->framebuf_cnt+1), sizeof(mpeg_frame_t));
if(spriv->framebuf == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(idx), abort\n");
@ -2018,6 +2020,11 @@ static int add_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr, int le
if(spriv->framebuf[idx].alloc_size < spriv->framebuf[idx].size + len)
{
if(spriv->framebuf[idx].size > SIZE_MAX - (size_t)len)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Size overflow, couldn't realloc frame buffer(frame), abort\n");
return -1;
}
spriv->framebuf[idx].buffer = realloc(spriv->framebuf[idx].buffer, spriv->framebuf[idx].size + len);
if(spriv->framebuf[idx].buffer == NULL)
{
@ -2329,6 +2336,11 @@ static void mpegfile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags
if(s->b_buffer_size - s->b_buffer_len < len)
{
if(s->b_buffer_len > SIZE_MAX - len)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "\nFATAL! couldn't realloc, integer overflow\n");
return;
}
s->b_buffer = realloc(s->b_buffer, len + s->b_buffer_len);
if(s->b_buffer == NULL)
{

View File

@ -354,7 +354,11 @@ int stream_control(stream_t *s, int cmd, void *arg){
}
stream_t* new_memory_stream(unsigned char* data,int len){
stream_t *s=malloc(sizeof(stream_t)+len);
stream_t *s;
if(len < 0)
return NULL;
s=malloc(sizeof(stream_t)+len);
memset(s,0,sizeof(stream_t));
s->fd=-1;
s->type=STREAMTYPE_MEMORY;

View File

@ -78,6 +78,8 @@ static int open_live_sdp(stream_t *stream,int mode, void* opts, int* file_format
lseek(f,0,SEEK_SET);
if(len == -1)
return STREAM_ERROR;
if(len > SIZE_MAX - 1)
return STREAM_ERROR;
sdpDescription = (char*)malloc(len+1);
if(sdpDescription == NULL) return STREAM_ERROR;

View File

@ -568,7 +568,7 @@ static int init(priv_t *priv)
}
mp_msg(MSGT_TV, MSGL_INFO, " Inputs: %d\n", priv->capability.channels);
priv->channels = (struct video_channel *)malloc(sizeof(struct video_channel)*priv->capability.channels);
priv->channels = (struct video_channel *)calloc(priv->capability.channels, sizeof(struct video_channel));
if (!priv->channels)
goto malloc_failed;
memset(priv->channels, 0, sizeof(struct video_channel)*priv->capability.channels);
@ -621,7 +621,7 @@ static int init(priv_t *priv)
priv->nbuf = priv->mbuf.frames;
/* video buffers */
priv->buf = (struct video_mmap *)malloc(priv->nbuf * sizeof(struct video_mmap));
priv->buf = (struct video_mmap *)calloc(priv->nbuf, sizeof(struct video_mmap));
if (!priv->buf)
goto malloc_failed;
memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));
@ -856,13 +856,13 @@ static int start(priv_t *priv)
if (!tv_param_noaudio) {
setup_audio_buffer_sizes(priv);
bytes_per_sample = priv->audio_in.bytes_per_sample;
priv->audio_skew_buffer = (long long*)malloc(sizeof(long long)*priv->aud_skew_cnt);
priv->audio_skew_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
if (!priv->audio_skew_buffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
return 0;
}
priv->audio_ringbuffer = (unsigned char*)malloc(priv->audio_in.blocksize*priv->audio_buffer_size);
priv->audio_ringbuffer = (unsigned char*)calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
if (!priv->audio_ringbuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
return 0;
@ -900,7 +900,7 @@ static int start(priv_t *priv)
priv->video_buffer_size_max,
priv->video_buffer_size_max*priv->height*priv->bytesperline/(1024*1024));
priv->video_ringbuffer = (unsigned char**)malloc(priv->video_buffer_size_max*sizeof(unsigned char*));
priv->video_ringbuffer = (unsigned char**)calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
if (!priv->video_ringbuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
return 0;
@ -908,7 +908,7 @@ static int start(priv_t *priv)
for (i = 0; i < priv->video_buffer_size_max; i++)
priv->video_ringbuffer[i] = NULL;
priv->video_timebuffer = (long long*)malloc(sizeof(long long) * priv->video_buffer_size_max);
priv->video_timebuffer = (long long*)calloc(priv->video_buffer_size_max, sizeof(long long));
if (!priv->video_timebuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
return 0;
@ -1569,7 +1569,7 @@ static void *video_grabber(void *data)
pthread_mutex_lock(&priv->video_buffer_mutex);
if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
if (priv->video_cnt == priv->video_buffer_size_current) {
unsigned char *newbuf = (unsigned char*)malloc(priv->bytesperline * priv->height);
unsigned char *newbuf = (unsigned char*)calloc(priv->bytesperline, priv->height);
if (newbuf) {
memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
(priv->video_buffer_size_current-priv->video_tail)*sizeof(unsigned char *));

View File

@ -1169,18 +1169,18 @@ static int start(priv_t *priv)
if (!tv_param_noaudio) {
setup_audio_buffer_sizes(priv);
priv->audio_skew_buffer = (long long*)malloc(sizeof(long long)*priv->aud_skew_cnt);
priv->audio_skew_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
if (!priv->audio_skew_buffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
return 0;
}
priv->audio_skew_delta_buffer = (long long*)malloc(sizeof(long long)*priv->aud_skew_cnt);
priv->audio_skew_delta_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
if (!priv->audio_skew_delta_buffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
return 0;
}
priv->audio_ringbuffer = (unsigned char*)malloc(priv->audio_in.blocksize*priv->audio_buffer_size);
priv->audio_ringbuffer = (unsigned char*)calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
if (!priv->audio_ringbuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
return 0;
@ -1226,14 +1226,14 @@ static int start(priv_t *priv)
priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
}
priv->video_ringbuffer = (unsigned char**)malloc(priv->video_buffer_size_max*sizeof(unsigned char*));
priv->video_ringbuffer = (unsigned char**)calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
if (!priv->video_ringbuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
return 0;
}
for (i = 0; i < priv->video_buffer_size_max; i++)
priv->video_ringbuffer[i] = NULL;
priv->video_timebuffer = (long long*)malloc(sizeof(long long) * priv->video_buffer_size_max);
priv->video_timebuffer = (long long*)calloc(priv->video_buffer_size_max, sizeof(long long));
if (!priv->video_timebuffer) {
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
return 0;
@ -1261,7 +1261,7 @@ static int start(priv_t *priv)
}
/* query buffers */
if (!(priv->map = malloc(sizeof(struct map) * request.count))) {
if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
info.short_name, strerror(errno));
return 0;
@ -1561,7 +1561,7 @@ static int get_video_framesize(priv_t *priv)
// for testing purposes only
static void read_doublespeed(priv_t *priv)
{
char *bufx = (char*)malloc(priv->audio_in.blocksize*2);
char *bufx = (char*)calloc(priv->audio_in.blocksize, 2);
short *s;
short *d;
int i;

View File

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
#include "url.h"
#include "mp_msg.h"
@ -24,6 +25,10 @@ url_new(const char* url) {
if( url==NULL ) return NULL;
if (strlen(url) > (SIZE_MAX / 3 - 1)) {
mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed);
goto err_out;
}
escfilename=malloc(strlen(url)*3+1);
if (!escfilename ) {
mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed);