diff --git a/libvorbis.spec b/libvorbis.spec index f84238e..6a87c70 100644 --- a/libvorbis.spec +++ b/libvorbis.spec @@ -1,13 +1,18 @@ Summary: The Vorbis General Audio Compression Codec. Name: libvorbis Version: 1.2.0 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 1 Group: System Environment/Libraries License: BSD URL: http://www.xiph.org/ Source: http://downloads.xiph.org/releases/vorbis/libvorbis-%{version}.tar.bz2 Patch0: libvorbis-1.0-m4.patch +Patch1: r14502.patch +Patch2: r14598-CVE-2008-1420.patch +Patch3: r14602-CVE-2008-1419.patch +Patch4: r14602-CVE-2008-1423.patch +Patch5: r14811.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libogg-devel >= 2:1.1 @@ -34,6 +39,11 @@ needed to develop applications with Ogg Vorbis. %setup -q %patch0 -p1 -b .m4 +%patch1 -p0 -b .r14502 +%patch2 -p0 -b .r14598-CVE-2008-1420 +%patch3 -p0 -b .r14602-CVE-2008-1419 +%patch4 -p0 -b .r14602-CVE-2008-1423 +%patch5 -p0 -b .r14811 perl -p -i -e "s/-O20/$RPM_OPT_FLAGS/" configure perl -p -i -e "s/-ffast-math//" configure # link to .pdf spec rather than ship redundant copy @@ -81,6 +91,9 @@ rm -rf $RPM_BUILD_ROOT %postun -p /sbin/ldconfig %changelog +* Wed May 14 2008 Jindrich Novy - 1:1.2.0-4 +- fix CVE-2008-1420, CVE-2008-1419, CVE-2008-1423 (#446344) + * Tue Feb 19 2008 Fedora Release Engineering - 1:1.2.0-3 - Autorebuild for GCC 4.3 diff --git a/r14502.patch b/r14502.patch new file mode 100644 index 0000000..bdb7dc6 --- /dev/null +++ b/r14502.patch @@ -0,0 +1,29 @@ +Index: lib/info.c +=================================================================== +--- lib/info.c (revision 14501) ++++ lib/info.c (revision 14502) +@@ -236,17 +236,21 @@ + int i; + int vendorlen=oggpack_read(opb,32); + if(vendorlen<0)goto err_out; ++ if(vendorlen+8>opb->storage)goto err_out; + vc->vendor=_ogg_calloc(vendorlen+1,1); + _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)goto err_out; ++ if(4*i+oggpack_bytes(opb)>opb->storage)goto err_out; ++ vc->comments=i; + vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); + vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); + + for(i=0;icomments;i++){ + int len=oggpack_read(opb,32); + if(len<0)goto err_out; +- vc->comment_lengths[i]=len; ++ if(len+oggpack_bytes(opb)>opb->storage)goto err_out; ++ vc->comment_lengths[i]=len; + vc->user_comments[i]=_ogg_calloc(len+1,1); + _v_readstring(opb,vc->user_comments[i],len); + } diff --git a/r14598-CVE-2008-1420.patch b/r14598-CVE-2008-1420.patch new file mode 100644 index 0000000..819cbf0 --- /dev/null +++ b/r14598-CVE-2008-1420.patch @@ -0,0 +1,34 @@ +Index: lib/res0.c +=================================================================== +--- lib/res0.c (revision 14597) ++++ lib/res0.c (revision 14598) +@@ -223,6 +223,20 @@ + for(j=0;jbooklist[j]>=ci->books)goto errout; + ++ /* verify the phrasebook is not specifying an impossible or ++ inconsistent partitioning scheme. */ ++ { ++ int entries = ci->book_param[info->groupbook]->entries; ++ int dim = ci->book_param[info->groupbook]->dim; ++ int partvals = 1; ++ while(dim>0){ ++ partvals *= info->partitions; ++ if(partvals > entries) goto errout; ++ dim--; ++ } ++ if(partvals != entries) goto errout; ++ } ++ + return(info); + errout: + res0_free_info(info); +@@ -263,7 +277,7 @@ + } + } + +- look->partvals=rint(pow((float)look->parts,(float)dim)); ++ look->partvals=look->phrasebook->entries; + look->stages=maxstage; + look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); + for(j=0;jpartvals;j++){ diff --git a/r14602-CVE-2008-1419.patch b/r14602-CVE-2008-1419.patch new file mode 100644 index 0000000..fd73f23 --- /dev/null +++ b/r14602-CVE-2008-1419.patch @@ -0,0 +1,13 @@ +Index: lib/codebook.c +=================================================================== +--- lib/codebook.c (revision 14601) ++++ lib/codebook.c (revision 14602) +@@ -225,7 +225,7 @@ + int quantvals=0; + switch(s->maptype){ + case 1: +- quantvals=_book_maptype1_quantvals(s); ++ quantvals=(s->dim==0?0:_book_maptype1_quantvals(s)); + break; + case 2: + quantvals=s->entries*s->dim; diff --git a/r14602-CVE-2008-1423.patch b/r14602-CVE-2008-1423.patch new file mode 100644 index 0000000..8c7c479 --- /dev/null +++ b/r14602-CVE-2008-1423.patch @@ -0,0 +1,13 @@ +Index: lib/codebook.c +=================================================================== +--- lib/codebook.c (revision 14603) ++++ lib/codebook.c (revision 14604) +@@ -159,6 +159,8 @@ + s->entries=oggpack_read(opb,24); + if(s->entries==-1)goto _eofout; + ++ if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; ++ + /* codeword ordering.... length ordered or unordered? */ + switch((int)oggpack_read(opb,1)){ + case 0: diff --git a/r14811.patch b/r14811.patch new file mode 100644 index 0000000..623773d --- /dev/null +++ b/r14811.patch @@ -0,0 +1,254 @@ +Index: doc/Vorbis_I_spec.pdf +=================================================================== +Cannot display: file marked as a binary type. +svn:mime-type = application/pdf +Index: lib/sharedbook.c +=================================================================== +--- lib/sharedbook.c (revision 14810) ++++ lib/sharedbook.c (revision 14811) +@@ -124,7 +124,14 @@ + }else + if(sparsecount==0)count++; + } +- ++ ++ /* sanity check the huffman tree; an underpopulated tree must be rejected. */ ++ for(i=1;i<33;i++) ++ if(marker[i] & (0xffffffffUL>>(32-i))){ ++ _ogg_free(r); ++ return(NULL); ++ } ++ + /* bitreverse the words because our bitwise packer/unpacker is LSb + endian */ + for(i=0,count=0;ifullbooks){ + ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); + for(i=0;ibooks;i++){ +- vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]); ++ if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])) ++ return -1; + /* decode codebooks are now standalone after init */ + vorbis_staticbook_destroy(ci->book_param[i]); + ci->book_param[i]=NULL; +@@ -694,9 +695,11 @@ + } + + int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){ +- if(_vds_shared_init(v,vi,0)) return 1; ++ if(_vds_shared_init(v,vi,0)){ ++ vorbis_dsp_clear(v); ++ return 1; ++ } + vorbis_synthesis_restart(v); +- + return 0; + } + +Index: examples/decoder_example.c +=================================================================== +--- examples/decoder_example.c (revision 14810) ++++ examples/decoder_example.c (revision 14811) +@@ -198,108 +198,111 @@ + + /* OK, got and parsed all three headers. Initialize the Vorbis + packet->PCM decoder. */ +- vorbis_synthesis_init(&vd,&vi); /* central decode state */ +- vorbis_block_init(&vd,&vb); /* local state for most of the decode +- so multiple block decodes can +- proceed in parallel. We could init +- multiple vorbis_block structures +- for vd here */ +- +- /* The rest is just a straight decode loop until end of stream */ +- while(!eos){ ++ if(vorbis_synthesis_init(&vd,&vi)==0){ /* central decode state */ ++ vorbis_block_init(&vd,&vb); /* local state for most of the decode ++ so multiple block decodes can ++ proceed in parallel. We could init ++ multiple vorbis_block structures ++ for vd here */ ++ ++ /* The rest is just a straight decode loop until end of stream */ + while(!eos){ +- int result=ogg_sync_pageout(&oy,&og); +- if(result==0)break; /* need more data */ +- if(result<0){ /* missing or corrupt data at this page position */ +- fprintf(stderr,"Corrupt or missing data in bitstream; " +- "continuing...\n"); +- }else{ +- ogg_stream_pagein(&os,&og); /* can safely ignore errors at +- this point */ +- while(1){ +- result=ogg_stream_packetout(&os,&op); +- +- if(result==0)break; /* need more data */ +- if(result<0){ /* missing or corrupt data at this page position */ +- /* no reason to complain; already complained above */ +- }else{ +- /* we have a packet. Decode it */ +- float **pcm; +- int samples; ++ while(!eos){ ++ int result=ogg_sync_pageout(&oy,&og); ++ if(result==0)break; /* need more data */ ++ if(result<0){ /* missing or corrupt data at this page position */ ++ fprintf(stderr,"Corrupt or missing data in bitstream; " ++ "continuing...\n"); ++ }else{ ++ ogg_stream_pagein(&os,&og); /* can safely ignore errors at ++ this point */ ++ while(1){ ++ result=ogg_stream_packetout(&os,&op); + +- if(vorbis_synthesis(&vb,&op)==0) /* test for success! */ +- vorbis_synthesis_blockin(&vd,&vb); +- /* +- +- **pcm is a multichannel float vector. In stereo, for +- example, pcm[0] is left, and pcm[1] is right. samples is +- the size of each channel. Convert the float values +- (-1.<=range<=1.) to whatever PCM format and write it out */ +- +- while((samples=vorbis_synthesis_pcmout(&vd,&pcm))>0){ +- int j; +- int clipflag=0; +- int bout=(samples0){ ++ int j; ++ int clipflag=0; ++ int bout=(samples32767){ +- val=32767; +- clipflag=1; ++ /* might as well guard against clipping */ ++ if(val>32767){ ++ val=32767; ++ clipflag=1; ++ } ++ if(val<-32768){ ++ val=-32768; ++ clipflag=1; ++ } ++ *ptr=val; ++ ptr+=vi.channels; + } +- if(val<-32768){ +- val=-32768; +- clipflag=1; +- } +- *ptr=val; +- ptr+=vi.channels; + } +- } +- +- if(clipflag) +- fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence)); +- +- +- fwrite(convbuffer,2*vi.channels,bout,stdout); +- +- vorbis_synthesis_read(&vd,bout); /* tell libvorbis how +- many samples we +- actually consumed */ +- } ++ ++ if(clipflag) ++ fprintf(stderr,"Clipping in frame %ld\n",(long)(vd.sequence)); ++ ++ ++ fwrite(convbuffer,2*vi.channels,bout,stdout); ++ ++ vorbis_synthesis_read(&vd,bout); /* tell libvorbis how ++ many samples we ++ actually consumed */ ++ } ++ } + } ++ if(ogg_page_eos(&og))eos=1; + } +- if(ogg_page_eos(&og))eos=1; + } ++ if(!eos){ ++ buffer=ogg_sync_buffer(&oy,4096); ++ bytes=fread(buffer,1,4096,stdin); ++ ogg_sync_wrote(&oy,bytes); ++ if(bytes==0)eos=1; ++ } + } +- if(!eos){ +- buffer=ogg_sync_buffer(&oy,4096); +- bytes=fread(buffer,1,4096,stdin); +- ogg_sync_wrote(&oy,bytes); +- if(bytes==0)eos=1; +- } ++ ++ /* ogg_page and ogg_packet structs always point to storage in ++ libvorbis. They're never freed or manipulated directly */ ++ ++ vorbis_block_clear(&vb); ++ vorbis_dsp_clear(&vd); ++ }else{ ++ fprintf(stderr,"Error: Corrupt header during playback initialization.\n"); + } +- ++ + /* clean up this logical bitstream; before exit we see if we're + followed by another [chained] */ +- ++ + ogg_stream_clear(&os); +- +- /* ogg_page and ogg_packet structs always point to storage in +- libvorbis. They're never freed or manipulated directly */ +- +- vorbis_block_clear(&vb); +- vorbis_dsp_clear(&vd); +- vorbis_comment_clear(&vc); ++ vorbis_comment_clear(&vc); + vorbis_info_clear(&vi); /* must be called last */ + } +