Project

General

Profile

Actions

Bug #15189

closed

Multiple OOB reads (of size 4) in rb_bigzero_p

Added by bannable (Joe Truba) over 3 years ago. Updated over 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.6.0dev (2018-10-01 trunk 64894) [x86_64-linux]
[ruby-core:89239]

Description

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.

For each reproducer, I have included:

  • the reproducer
  • stdout from ruby
  • gdb backtrace
  • valgrind report

Files

crashes.rb_bigzero_p.zip (104 KB) crashes.rb_bigzero_p.zip bannable (Joe Truba), 10/01/2018 07:58 PM

Related issues

Has duplicate Ruby master - Bug #15191: Segfault in bignum.c bigtrunc()ClosedActions

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

Thank you for the report.

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:

crash01/reproducer:111r+11**-11111161111111
crash02/reproducer:1118111111111**-1111111111111111**1+1==11111
crash03/reproducer:-1111111**-1111*11 - -1111111** -111111111
crash04/reproducer:1118111111111** -1111111111111111**1+11111111111**1 ===111
crash05/reproducer:11** -111155555555555555  -55   !=5-555
crash07/reproducer:1 + 111111111**-1111811111
crash08/reproducer:18111111111**-1111111111111111**1 + 1111111111**-1111**1
crash10/reproducer:-7 - -1111111** -1111**11
crash12/reproducer:1118111111111** -1111111111111111**1 + 1111 - -1111111** -1111*111111111119
crash13/reproducer:1.0i - -1111111** -111111111
crash14/reproducer:11111**111111111**111111 * -11111111111111111111**-111111111111
crash15/reproducer:~1**1111 + -~1**~1**111
crash17/reproducer:11** -1111111**1111 /11i
crash18/reproducer:5555i**-5155 - -9111111**-1111**11
crash19/reproducer:111111 < 111111*-11111111111111111111**-1111111111111111
crash20/reproducer:1111**111-11**-11111**11
crash21/reproducer:11**-10111111119-1i -1r

Updated by bannable (Joe Truba) over 3 years ago

nobu (Nobuyoshi Nakada) wrote:

Thank you for the report.

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.

Actions #3

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r64897.


Fix Rational of Float

[ruby-core:89239] [Bug #15189]

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

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.

Actions #5

Updated by nobu (Nobuyoshi Nakada) over 3 years ago

  • Has duplicate Bug #15191: Segfault in bignum.c bigtrunc() added
Actions

Also available in: Atom PDF