Actions
Bug #12423
closedRegexp: Heap Buffer Overflow in regparse.c : next_state_value()
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.1p112 (2016-04-26 revision 54768) [i686-linux]
Backport:
Description
A crafted regular expression will cause a heap buffer overflow leading to invalid 4 byte reads/writes on 32-bit Ubuntu 14.04. The regular expression fails to close a character class and has an octal zero as the first character in the character class.
Despite the buffer overflow, ruby does not crash. This bug may have the same root cause as #12420.
grajagandev# cat load-re.rb
File.open(ARGV[0]) do |f|
@re = Regexp.new("/" + File.read(f) + "/")
end
grajagandev# xxd overflow-next_state_value
0000000: 5b5c 3630 3030 3030 3030 3030 3030 0a [\600000000000.
grajagandev# ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [i686-linux]
grajagandev# uname -a
Linux x-Acer 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015 i686 i686 i686 GNU/Linux
grajagandev# ruby load-re.rb overflow-next_state_value
=================================================================
==11873== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb470cd88 at pc 0xb730f9fd bp 0xbfc4d458 sp 0xbfc4d44c
READ of size 4 at 0xb470cd88 thread T0
#0 0xb730f9fc (/usr/local/bin/ruby+0x1cb9fc)
#1 0xb73116c9 (/usr/local/bin/ruby+0x1cd6c9)
#2 0xb731a6fb (/usr/local/bin/ruby+0x1d66fb)
#3 0xb731b856 (/usr/local/bin/ruby+0x1d7856)
#4 0xb731baee (/usr/local/bin/ruby+0x1d7aee)
#5 0xb731bdd9 (/usr/local/bin/ruby+0x1d7dd9)
#6 0xb731c376 (/usr/local/bin/ruby+0x1d8376)
#7 0xb72ccf09 (/usr/local/bin/ruby+0x188f09)
#8 0xb729a77f (/usr/local/bin/ruby+0x15677f)
#9 0xb729a8b6 (/usr/local/bin/ruby+0x1568b6)
#10 0xb72a586e (/usr/local/bin/ruby+0x16186e)
#11 0xb72a5bc1 (/usr/local/bin/ruby+0x161bc1)
#12 0xb72a943c (/usr/local/bin/ruby+0x16543c)
#13 0xb7450da4 (/usr/local/bin/ruby+0x30cda4)
#14 0xb74844a6 (/usr/local/bin/ruby+0x3404a6)
#15 0xb74845fc (/usr/local/bin/ruby+0x3405fc)
#16 0xb7484be3 (/usr/local/bin/ruby+0x340be3)
#17 0xb7483fbd (/usr/local/bin/ruby+0x33ffbd)
#18 0xb74860ed (/usr/local/bin/ruby+0x3420ed)
#19 0xb748763d (/usr/local/bin/ruby+0x34363d)
#20 0xb74884cd (/usr/local/bin/ruby+0x3444cd)
#21 0xb718477e (/usr/local/bin/ruby+0x4077e)
#22 0xb72549ed (/usr/local/bin/ruby+0x1109ed)
#23 0xb7450da4 (/usr/local/bin/ruby+0x30cda4)
#24 0xb745342d (/usr/local/bin/ruby+0x30f42d)
#25 0xb745368d (/usr/local/bin/ruby+0x30f68d)
#26 0xb7456088 (/usr/local/bin/ruby+0x312088)
#27 0xb74574da (/usr/local/bin/ruby+0x3134da)
#28 0xb74578b2 (/usr/local/bin/ruby+0x3138b2)
#29 0xb7465a0b (/usr/local/bin/ruby+0x321a0b)
#30 0xb749718c (/usr/local/bin/ruby+0x35318c)
#31 0xb7492c08 (/usr/local/bin/ruby+0x34ec08)
#32 0xb74935db (/usr/local/bin/ruby+0x34f5db)
#33 0xb7493686 (/usr/local/bin/ruby+0x34f686)
#34 0xb7493882 (/usr/local/bin/ruby+0x34f882)
#35 0xb7488eae (/usr/local/bin/ruby+0x344eae)
#36 0xb7488ecd (/usr/local/bin/ruby+0x344ecd)
#37 0xb7488efc (/usr/local/bin/ruby+0x344efc)
#38 0xb718289f (/usr/local/bin/ruby+0x3e89f)
#39 0xb7203f64 (/usr/local/bin/ruby+0xbff64)
#40 0xb7450da4 (/usr/local/bin/ruby+0x30cda4)
#41 0xb745342d (/usr/local/bin/ruby+0x30f42d)
#42 0xb745368d (/usr/local/bin/ruby+0x30f68d)
#43 0xb7456088 (/usr/local/bin/ruby+0x312088)
#44 0xb74574da (/usr/local/bin/ruby+0x3134da)
#45 0xb74578b2 (/usr/local/bin/ruby+0x3138b2)
#46 0xb746510f (/usr/local/bin/ruby+0x32110f)
#47 0xb749718c (/usr/local/bin/ruby+0x35318c)
#48 0xb74997a5 (/usr/local/bin/ruby+0x3557a5)
#49 0xb717f669 (/usr/local/bin/ruby+0x3b669)
#50 0xb717f8cd (/usr/local/bin/ruby+0x3b8cd)
#51 0xb717f882 (/usr/local/bin/ruby+0x3b882)
#52 0xb717a1a3 (/usr/local/bin/ruby+0x361a3)
#53 0xb58f6a82 (/lib/i386-linux-gnu/libc-2.19.so+0x19a82)
#54 0xb7179fd0 (/usr/local/bin/ruby+0x35fd0)
0xb470cd88 is located 8 bytes to the left of 44-byte region [0xb470cd90,0xb470cdbc)
allocated by thread T0 here:
#0 0xb5b3a854 (/usr/lib/i386-linux-gnu/libasan.so.0.0.0+0x16854)
#1 0xb72f61f2 (/usr/local/bin/ruby+0x1b21f2)
#2 0xb72f7d84 (/usr/local/bin/ruby+0x1b3d84)
#3 0xb731b245 (/usr/local/bin/ruby+0x1d7245)
#4 0xb731b75d (/usr/local/bin/ruby+0x1d775d)
#5 0xb731baee (/usr/local/bin/ruby+0x1d7aee)
#6 0xb7315d4c (/usr/local/bin/ruby+0x1d1d4c)
#7 0xb7318dc0 (/usr/local/bin/ruby+0x1d4dc0)
#8 0xb731b856 (/usr/local/bin/ruby+0x1d7856)
#9 0xb731baee (/usr/local/bin/ruby+0x1d7aee)
#10 0xb731bdd9 (/usr/local/bin/ruby+0x1d7dd9)
#11 0xb731c376 (/usr/local/bin/ruby+0x1d8376)
#12 0xb72ccf09 (/usr/local/bin/ruby+0x188f09)
#13 0xb729a77f (/usr/local/bin/ruby+0x15677f)
#14 0xb729a8b6 (/usr/local/bin/ruby+0x1568b6)
#15 0xb72a586e (/usr/local/bin/ruby+0x16186e)
#16 0xb72a5bc1 (/usr/local/bin/ruby+0x161bc1)
#17 0xb72a62cf (/usr/local/bin/ruby+0x1622cf)
#18 0xb75afcb2 (/usr/local/bin/ruby+0x46bcb2)
#19 0xb75afcef (/usr/local/bin/ruby+0x46bcef)
#20 0xb757ff6a (/usr/local/bin/ruby+0x43bf6a)
#21 0xb758a473 (/usr/local/bin/ruby+0x446473)
#22 0xb74acc2c (/usr/local/bin/ruby+0x368c2c)
#23 0xb758aa46 (/usr/local/bin/ruby+0x446a46)
#24 0xb758b64c (/usr/local/bin/ruby+0x44764c)
#25 0xb7326787 (/usr/local/bin/ruby+0x1e2787)
#26 0xb718289f (/usr/local/bin/ruby+0x3e89f)
#27 0xb7327029 (/usr/local/bin/ruby+0x1e3029)
#28 0xb73270f2 (/usr/local/bin/ruby+0x1e30f2)
#29 0xb7189871 (/usr/local/bin/ruby+0x45871)
Shadow bytes around the buggy address:
0x368e1960: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa
0x368e1970: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 04
0x368e1980: fa fa 00 00 00 00 00 04 fa fa 00 00 00 00 00 04
0x368e1990: fa fa 00 00 00 00 00 04 fa fa 00 00 00 00 00 04
0x368e19a0: fa fa 00 00 00 00 00 04 fa fa 00 00 00 00 00 04
=>0x368e19b0: fa[fa]00 00 00 00 00 04 fa fa 00 00 00 00 00 04
0x368e19c0: fa fa 00 00 00 00 00 04 fa fa 00 00 00 00 00 04
0x368e19d0: fa fa 00 00 00 00 00 04 fa fa 00 00 00 00 00 fa
0x368e19e0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
0x368e19f0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
0x368e1a00: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap righ redzone: fb
Freed Heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==11873== ABORTING
grajagandev#
grajagandev# valgrind --max-stackframe=90000000 ruby load-re.rb overflow-next_state_value
==23692== Memcheck, a memory error detector
==23692== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==23692== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==23692== Command: ruby load-re.rb overflow-next_state_value
==23692==
==23692== Invalid read of size 4
==23692== at 0x1C9588: next_state_val (regparse.c:4478)
==23692== by 0x1CA0D7: parse_char_class (regparse.c:4725)
==23692== by 0x1CD36D: parse_exp (regparse.c:6187)
==23692== by 0x1CD8F5: parse_branch (regparse.c:6365)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692== Address 0x4cb6180 is 12 bytes after a block of size 44 alloc'd
==23692== at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==23692== by 0x1C14CD: node_new (regparse.c:1151)
==23692== by 0x1C17D0: node_new_list (regparse.c:1291)
==23692== by 0x1CD953: parse_branch (regparse.c:6377)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692==
==23692== Invalid read of size 4
==23692== at 0x1C95CB: next_state_val (regparse.c:4478)
==23692== by 0x1CA0D7: parse_char_class (regparse.c:4725)
==23692== by 0x1CD36D: parse_exp (regparse.c:6187)
==23692== by 0x1CD8F5: parse_branch (regparse.c:6365)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692== Address 0x4cb6180 is 12 bytes after a block of size 44 alloc'd
==23692== at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==23692== by 0x1C14CD: node_new (regparse.c:1151)
==23692== by 0x1C17D0: node_new_list (regparse.c:1291)
==23692== by 0x1CD953: parse_branch (regparse.c:6377)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692==
==23692== Invalid write of size 4
==23692== at 0x1C95F5: next_state_val (regparse.c:4478)
==23692== by 0x1CA0D7: parse_char_class (regparse.c:4725)
==23692== by 0x1CD36D: parse_exp (regparse.c:6187)
==23692== by 0x1CD8F5: parse_branch (regparse.c:6365)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692== Address 0x4cb6180 is 12 bytes after a block of size 44 alloc'd
==23692== at 0x482A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==23692== by 0x1C14CD: node_new (regparse.c:1151)
==23692== by 0x1C17D0: node_new_list (regparse.c:1291)
==23692== by 0x1CD953: parse_branch (regparse.c:6377)
==23692== by 0x1CD9BD: parse_subexp (regparse.c:6395)
==23692== by 0x1CDB5D: parse_regexp (regparse.c:6443)
==23692== by 0x1CDC80: onig_parse_make_tree (regparse.c:6485)
==23692== by 0x1B27C6: onig_compile (regcomp.c:5739)
==23692== by 0x1A0C20: onig_new_with_source (re.c:849)
==23692== by 0x1A0CA8: make_regexp (re.c:873)
==23692== by 0x1A479D: rb_reg_initialize (re.c:2546)
==23692== by 0x1A4905: rb_reg_initialize_str (re.c:2571)
==23692==
load-re.rb:2:in `initialize': premature end of char-class: /\/[\600000000000 (RegexpError)
\//
from load-re.rb:2:in `new'
from load-re.rb:2:in `block in <main>'
from load-re.rb:1:in `open'
from load-re.rb:1:in `<main>'
==23692==
==23692== HEAP SUMMARY:
==23692== in use at exit: 1,796,552 bytes in 27,452 blocks
==23692== total heap usage: 52,413 allocs, 24,961 frees, 6,176,416 bytes allocated
==23692==
==23692== LEAK SUMMARY:
==23692== definitely lost: 289,615 bytes in 6,018 blocks
==23692== indirectly lost: 341,542 bytes in 7,685 blocks
==23692== possibly lost: 994,526 bytes in 9,609 blocks
==23692== still reachable: 170,869 bytes in 4,140 blocks
==23692== suppressed: 0 bytes in 0 blocks
==23692== Rerun with --leak-check=full to see details of leaked memory
==23692==
==23692== For counts of detected and suppressed errors, rerun with: -v
==23692== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Files
Updated by naruse (Yui NARUSE) over 8 years ago
- Status changed from Open to Closed
Updated by usa (Usaku NAKAMURA) over 8 years ago
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED
Updated by usa (Usaku NAKAMURA) over 8 years ago
- Related to Bug #12420: Regexp: Segfault due to Invalid Read in regparse.c : bbuf_free() added
Updated by usa (Usaku NAKAMURA) over 8 years ago
- Backport changed from 2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED to 2.1: WONTFIX, 2.2: DONE, 2.3: REQUIRED
ruby_2_2 r55363 merged revision(s) 55163,55165.
Updated by nagachika (Tomoyuki Chikanaga) over 8 years ago
- Backport changed from 2.1: WONTFIX, 2.2: DONE, 2.3: REQUIRED to 2.1: WONTFIX, 2.2: DONE, 2.3: DONE
ruby_2_3 r55458 merged revision(s) 55163,55165.
Actions
Like0
Like0Like0Like0Like0Like0