(CVE-2017-14632)call oggpack_writeclear() with uninitialized stack var opb in function vorbis_analysis_headerout() when vi->channels<=0 in libvorbis 1.3.5
int vorbis_analysis_headerout(vorbis_dsp_state *v,
577 vorbis_comment *vc,
578 ogg_packet *op,
579 ogg_packet *op_comm,
580 ogg_packet *op_code){
581 int ret=OV_EIMPL;
582 vorbis_info *vi=v->vi;
583 oggpack_buffer opb;
584 private_state *b=v->backend_state;
585
586 if(!b||vi->channels<=0){
587 ret=OV_EFAULT;
588 goto err_out;
589 }
...
639 err_out:
640 memset(op,0,sizeof(*op));
641 memset(op_comm,0,sizeof(*op_comm));
642 memset(op_code,0,sizeof(*op_code));
643
644 if(b){
645 oggpack_writeclear(&opb);
646 if(b->header)_ogg_free(b->header);
647 if(b->header1)_ogg_free(b->header1);
648 if(b->header2)_ogg_free(b->header2);
649 b->header=NULL;
650 b->header1=NULL;
651 b->header2=NULL;
652 }
as shown above, if vi->channels<=0 and b!=NULL then func goes to err_out with opb uninitialized, but before calling oggpack_writeclear, it only check if(b),so it will ultimately free a uninitialized memory in oggpack_writeclear:
250 void oggpack_writeclear(oggpack_buffer *b){
251 if(b->buffer)_ogg_free(b->buffer);
252 memset(b,0,sizeof(*b));
253 }
This vul may lead to a DOS or Remote Code Execution in products using libvorbis 1.3.5(latest version).
By the way, I found 8 years ago this function has been found a similar vul :https://bugzilla.mozilla.org/show_bug.cgi?id=550184
while cause of no check of if b=NULL before calling oggpack_writeclear. This time , it is because of incorrect check while no considering if vi->channels<=0.
To reproduce this vul, compile libtheora 1.1.1 libvorbis 1.3.5 libogg 1.3.2 ,then run as below:
╭─root@linux-jiangxin in /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/fuzz
╰$ gdb ../examples/encoder_example
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../examples/encoder_example...done.
(gdb) run out/Master/crashes/id:000000,sig:06,src:000000,op:flip1,pos:22 xxx.y4m
Starting program: /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example out/Master/crashes/id:000000,sig:06,src:000000,op:flip1,pos:22 xxx.y4m
File out/Master/crashes/id:000000,sig:06,src:000000,op:flip1,pos:22 is 16 bit 0 channel 44100 Hz RIFF WAV audio.
File xxx.y4m is 176x144 29.97 fps mono video.
*** glibc detected *** /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example: munmap_chunk(): invalid pointer: 0x00007fffffffdb30 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76628)[0x7ffff7864628]
/home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example[0x4a4505]
/home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example[0x504090]
/home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example[0x40535d]
/lib64/libc.so.6(__libc_start_main+0xe6)[0x7ffff780cc36]
/home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example[0x40a039]
======= Memory map: ========
00400000-0063a000 r-xp 00000000 08:08 6452963 /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example
00839000-0083a000 r--p 00239000 08:08 6452963 /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example
0083a000-0083b000 rw-p 0023a000 08:08 6452963 /home/jiangxin/experiment/fuzz/AFL/target/libtheora-1.1.1/examples/encoder_example
0083b000-008e6000 rw-p 00000000 00:00 0 [heap]
7ffff75d7000-7ffff75ed000 r-xp 00000000 08:07 155653 /usr/local/lib64/libgcc_s.so.1
7ffff75ed000-7ffff77ec000 ---p 00016000 08:07 155653 /usr/local/lib64/libgcc_s.so.1
7ffff77ec000-7ffff77ed000 r--p 00015000 08:07 155653 /usr/local/lib64/libgcc_s.so.1
7ffff77ed000-7ffff77ee000 rw-p 00016000 08:07 155653 /usr/local/lib64/libgcc_s.so.1
7ffff77ee000-7ffff795c000 r-xp 00000000 08:07 131081 /lib64/libc-2.11.3.so
7ffff795c000-7ffff7b5b000 ---p 0016e000 08:07 131081 /lib64/libc-2.11.3.so
7ffff7b5b000-7ffff7b5f000 r--p 0016d000 08:07 131081 /lib64/libc-2.11.3.so
7ffff7b5f000-7ffff7b60000 rw-p 00171000 08:07 131081 /lib64/libc-2.11.3.so
7ffff7b60000-7ffff7b65000 rw-p 00000000 00:00 0
7ffff7b65000-7ffff7bc0000 r-xp 00000000 08:07 131089 /lib64/libm-2.11.3.so
7ffff7bc0000-7ffff7dbf000 ---p 0005b000 08:07 131089 /lib64/libm-2.11.3.so
7ffff7dbf000-7ffff7dc0000 r--p 0005a000 08:07 131089 /lib64/libm-2.11.3.so
7ffff7dc0000-7ffff7dde000 rw-p 0005b000 08:07 131089 /lib64/libm-2.11.3.so
7ffff7dde000-7ffff7dfd000 r-xp 00000000 08:07 131074 /lib64/ld-2.11.3.so
7ffff7f24000-7ffff7fc1000 rw-p 00000000 00:00 0
7ffff7fc8000-7ffff7ff8000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 0001e000 08:07 131074 /lib64/ld-2.11.3.so
7ffff7ffd000-7ffff7ffe000 rw-p 0001f000 08:07 131074 /lib64/ld-2.11.3.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
OggSa8W!۰ہ*theora
°u0迵@
Program received signal SIGABRT, Aborted.
0x00007ffff7820b55 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff7820b55 in raise () from /lib64/libc.so.6
#1 0x00007ffff7822131 in abort () from /lib64/libc.so.6
#2 0x00007ffff785ee0f in __libc_message () from /lib64/libc.so.6
#3 0x00007ffff7864628 in malloc_printerr () from /lib64/libc.so.6
#4 0x00000000004a4505 in oggpack_writeclear (b=b@entry=0x7fffffffda10) at bitwise.c:251
#5 0x0000000000504090 in vorbis_analysis_headerout (v=v@entry=0x7fffffffdcb0, vc=vc@entry=0x7fffffffdb50, op=op@entry=0x7fffffffdba0, op_comm=op_comm@entry=0x7fffffffdbd0, op_code=op_code@entry=0x7fffffffdc00) at info.c:645
#6 0x000000000040535d in main (argc=<optimized out>, argv=<optimized out>) at encoder_example.c:1688
(gdb) detach
files attached:
weird, I can not attach file here, so if you need please contact me for the the crash sample.
This issue has been assigned a CVE number :CVE-2017-14632
Edited by Jiangxin