From 3b652007d8f5e9e9201836d4a56829dffbe00673 Mon Sep 17 00:00:00 2001 From: Tim Terriberry Date: Sat, 16 Oct 2010 21:30:28 +0000 Subject: Additional codebook validity checks. Bail out of codebook loading early if the packet doesn't have enough data for the size of the codebooks it asked for. This doesn't in and of itself provide any additional security, but it does make peak heap usage on many invalid files smaller. git-svn-id: https://svn.xiph.org/trunk/Tremor@17539 0101bb08-14d6-0310-b084-bc0e0c8e3800 --- codebook.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/codebook.c b/codebook.c index 95bd34a..3844ddc 100644 --- a/codebook.c +++ b/codebook.c @@ -41,12 +41,17 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ /* codeword ordering.... length ordered or unordered? */ switch((int)oggpack_read(opb,1)){ - case 0: + case 0:{ + long unused; + /* allocated but unused entries? */ + unused=oggpack_read(opb,1); + if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb)) + goto _eofout; /* unordered */ s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); /* allocated but unused entries? */ - if(oggpack_read(opb,1)){ + if(unused){ /* yes, unused entries */ for(i=0;ientries;i++){ @@ -67,17 +72,22 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ } break; + } case 1: /* ordered */ { long length=oggpack_read(opb,5)+1; + if(length==0)goto _eofout; s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); for(i=0;ientries;){ long num=oggpack_read(opb,_ilog(s->entries-i)); if(num==-1)goto _eofout; - if(length>32)goto _errout; - for(j=0;jentries;j++,i++) + if(length>32 || num>s->entries-i || + (num>0 && num-1>>(length>>1)>>((length+1)>>1))>0){ + goto _errout; + } + for(j=0;jlengthlist[i]=length; length++; } @@ -115,6 +125,8 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ } /* quantized values */ + if((quantvals*s->q_quant+7)>>3>opb->storage-oggpack_bytes(opb)) + goto _eofout; s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals); for(i=0;iquantlist[i]=oggpack_read(opb,s->q_quant); -- cgit v1.2.1