summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Terriberry <tterribe@xiph.org>2010-10-16 21:30:28 +0000
committerTim Terriberry <tterribe@xiph.org>2010-10-16 21:30:28 +0000
commit3b652007d8f5e9e9201836d4a56829dffbe00673 (patch)
tree0314c28092ca95534a4044806aa3e205483c0038
parent3ada73cc10e6da279bf3b6458e30343ed7d2f01e (diff)
downloadtremor-3b652007d8f5e9e9201836d4a56829dffbe00673.tar.gz
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
-rw-r--r--codebook.c20
1 files 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;i<s->entries;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;i<s->entries;){
long num=oggpack_read(opb,_ilog(s->entries-i));
if(num==-1)goto _eofout;
- if(length>32)goto _errout;
- for(j=0;j<num && i<s->entries;j++,i++)
+ if(length>32 || num>s->entries-i ||
+ (num>0 && num-1>>(length>>1)>>((length+1)>>1))>0){
+ goto _errout;
+ }
+ for(j=0;j<num;j++,i++)
s->lengthlist[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;i<quantvals;i++)
s->quantlist[i]=oggpack_read(opb,s->q_quant);