An AFL fuzzing session against 6b4d78fc43 this weekend and turned up 17 crashes in rb_bigzero_p.
I suspect that all of these are the same underlying bug -- they are all a 4 byte OOB read in rb_bigzero_p -- so I'm including all of them in this single issue. If you'd like me to report each of these separately let me know and I'll happily do that.
Your reproducers seem often duplicated, and note that \0 is treated as the EOF in the parser and anything after it has no effect at all.
Reduced (but not smallest) code are:
...
Thank you for the info about \0, I'll keep an eye out for that.
The reproducers were deduplicated based on a hash of their crash backtrace, using afl-collect from afl-utils. Which ones were duplicated? I can see about trying to filter them in the future.
I notice that some of the reduced ones you've produced result in a different trace. Are you sure all of them are equivalent to the originals? For example, crash02 becomes:
#0 0x0000555555744922 in rb_bigzero_p (x=<optimized out>) at bignum.c:2910
#1 0x000055555564b495 in nurat_eqeq_p (self=0x555555adb6a0, other=0x56cf) at rational.c:1150
#2 0x0000555555704dc2 in vm_call_cfunc_with_frame (ci=0x555555bd22d0, cc=<optimized out>, calling=<optimized out>, reg_cfp=0x7ffff7fd2fa0, ec=0x555555abd8b8) at vm_insnhelper.c:1928
#3 vm_call_cfunc (ec=0x555555abd8b8, reg_cfp=0x7ffff7fd2fa0, calling=<optimized out>, ci=0x555555bd22d0, cc=<optimized out>) at vm_insnhelper.c:1944
#4 0x000055555570f263 in vm_call_method (ec=0x555555abd8b8, cfp=0x7ffff7fd2fa0, calling=<optimized out>, ci=<optimized out>, cc=<optimized out>) at vm_insnhelper.c:2418
...
instead of:
#0 0x0000555555964d6f in rb_bigzero_p (x=0x7ffff5d8f6d8) at bignum.c:2910
#1 0x000055555572d033 in nurat_eqeq_p (self=0x7ffff5d8f688, other=0x56cf) at rational.c:1150
#2 0x0000555555904df5 in call_cfunc_1 (func=0x0, recv=0x7ffff5d8f6d8, argc=<optimized out>, argv=<optimized out>) at ./vm_insnhelper.c:1775
#3 0x00005555558f382d in vm_call_cfunc_with_frame (ec=<optimized out>, reg_cfp=<optimized out>, calling=<optimized out>, ci=<optimized out>, cc=<optimized out>) at ./vm_insnhelper.c:1928
#4 vm_call_cfunc (ec=<optimized out>, reg_cfp=<optimized out>, calling=<optimized out>, ci=<optimized out>, cc=<optimized out>) at ./vm_insnhelper.c:1944
They have a different call path, get optimized differently, and look to wind up with different inputs. I am not familiar enough with the VM yet to know if these are the same effect.
I'm not sure what caused the difference, and call_cfunc_1 does not appear in both code on my machine.
That function should be simple enough to be eliminated by tail-call optimization.