summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Terriberry <tterribe@xiph.org>2010-10-13 20:58:52 +0000
committerTim Terriberry <tterribe@xiph.org>2010-10-13 20:58:52 +0000
commit69dfba92c6a0b872273ae79a832d89d6e83a7363 (patch)
tree2119e06ede0c01edf1db30cb96ae19032862e52f
parent7e94eea57d11795c88fc88124be43e5cd7af0636 (diff)
downloadtremor-69dfba92c6a0b872273ae79a832d89d6e83a7363.tar.gz
Forward port r14502, r16217, and parts of r16222.
Don't try to read past the end of the comment packet if the string lengths are corrupt. Correct a potential comment length sanity check overflow. Commit additional hardening to comment packet decode. Also add allocation checks, since these can still run us out of address space if someone actually sends a GB or two of comment data. git-svn-id: https://svn.xiph.org/trunk/Tremor@17514 0101bb08-14d6-0310-b084-bc0e0c8e3800
-rw-r--r--info.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/info.c b/info.c
index 71166e4..f351a48 100644
--- a/info.c
+++ b/info.c
@@ -186,22 +186,31 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
int i;
- int vendorlen=oggpack_read(opb,32);
+ int vendorlen;
+ vendorlen=oggpack_read(opb,32);
if(vendorlen<0)goto err_out;
+ if(vendorlen>opb->storage-oggpack_bytes(opb))goto err_out;
vc->vendor=(char *)_ogg_calloc(vendorlen+1,1);
+ if(vc->vendor==NULL)goto err_out;
_v_readstring(opb,vc->vendor,vendorlen);
- vc->comments=oggpack_read(opb,32);
- if(vc->comments<0)goto err_out;
+ i=oggpack_read(opb,32);
+ if(i<0||i>(opb->storage-oggpack_bytes(opb))>>2)goto err_out;
vc->user_comments=(char **)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
vc->comment_lengths=(int *)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
-
+ if(vc->user_comments==NULL||vc->comment_lengths==NULL)goto err_out;
+ vc->comments=i;
+
for(i=0;i<vc->comments;i++){
int len=oggpack_read(opb,32);
- if(len<0)goto err_out;
- vc->comment_lengths[i]=len;
+ if(len<0||len>opb->storage-oggpack_bytes(opb))goto err_out;
+ vc->comment_lengths[i]=len;
vc->user_comments[i]=(char *)_ogg_calloc(len+1,1);
+ if(vc->user_comments[i]==NULL){
+ vc->comments=i;
+ goto err_out;
+ }
_v_readstring(opb,vc->user_comments[i],len);
- }
+ }
if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
return(0);