summaryrefslogtreecommitdiffhomepage
path: root/test/t/hash.rb
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2021-02-10 20:03:34 +0900
committerKOBAYASHI Shuji <[email protected]>2021-02-10 20:03:34 +0900
commit28eb6271ba231fb8a6bfc2110b06e24c410bf8e1 (patch)
tree9ce2fd57f23195d56a8549e84fe57f276fea13a3 /test/t/hash.rb
parent20342714ea2d01687909aea3dbd2d43877e5a571 (diff)
downloadmruby-28eb6271ba231fb8a6bfc2110b06e24c410bf8e1.tar.gz
mruby-28eb6271ba231fb8a6bfc2110b06e24c410bf8e1.zip
Fix heap-buffer-overflow for small `Hash` (HT) in `Hash#rehash`
### Example ##### example.rb ```ruby h = {} (1..17).each{h[_1] = _1} (1..16).each{h.delete(_1)} h.rehash ``` ##### ASAN report ```console $ bin/mruby example.rb ==52587==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000006998 at pc 0x55a29cddf96b bp 0x7fff7b1b1720 sp 0x7fff7b1b1710 READ of size 4 at 0x602000006998 thread T0 #0 0x55a29cddf96a in ib_it_next /mruby/src/hash.c:639 #1 0x55a29cde2ca2 in ht_rehash /mruby/src/hash.c:900 #2 0x55a29cde379f in h_rehash /mruby/src/hash.c:996 #3 0x55a29cde7f3d in mrb_hash_rehash /mruby/src/hash.c:1735 #4 0x55a29ce77b62 in mrb_vm_exec /mruby/src/vm.c:1451 #5 0x55a29ce5fa88 in mrb_vm_run /mruby/src/vm.c:981 #6 0x55a29ceb87e1 in mrb_top_run /mruby/src/vm.c:2874 #7 0x55a29cf36bdf in mrb_load_exec mrbgems/mruby-compiler/core/parse.y:6805 #8 0x55a29cf36f25 in mrb_load_detect_file_cxt mrbgems/mruby-compiler/core/parse.y:6848 #9 0x55a29cdba0a2 in main /mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c:347 #10 0x7f24ef43b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) #11 0x55a29cdb4a6d in _start (/mruby/bin/mruby+0x2a3a6d) 0x602000006998 is located 0 bytes to the right of 8-byte region [0x602000006990,0x602000006998) allocated by thread T0 here: #0 0x7f24f01cfffe in __interceptor_realloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dffe) #1 0x55a29ceb9440 in mrb_default_allocf /mruby/src/state.c:68 #2 0x55a29cdba747 in mrb_realloc_simple /mruby/src/gc.c:228 #3 0x55a29cdba928 in mrb_realloc /mruby/src/gc.c:242 #4 0x55a29cde12e5 in ht_init /mruby/src/hash.c:749 #5 0x55a29cde2b8e in ht_rehash /mruby/src/hash.c:897 #6 0x55a29cde379f in h_rehash /mruby/src/hash.c:996 #7 0x55a29cde7f3d in mrb_hash_rehash /mruby/src/hash.c:1735 #8 0x55a29ce77b62 in mrb_vm_exec /mruby/src/vm.c:1451 #9 0x55a29ce5fa88 in mrb_vm_run /mruby/src/vm.c:981 #10 0x55a29ceb87e1 in mrb_top_run /mruby/src/vm.c:2874 #11 0x55a29cf36bdf in mrb_load_exec mrbgems/mruby-compiler/core/parse.y:6805 #12 0x55a29cf36f25 in mrb_load_detect_file_cxt mrbgems/mruby-compiler/core/parse.y:6848 #13 0x55a29cdba0a2 in main /mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c:347 #14 0x7f24ef43b0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) ```
Diffstat (limited to 'test/t/hash.rb')
-rw-r--r--test/t/hash.rb8
1 files changed, 8 insertions, 0 deletions
diff --git a/test/t/hash.rb b/test/t/hash.rb
index c51af03aa..a5e51d83b 100644
--- a/test/t/hash.rb
+++ b/test/t/hash.rb
@@ -944,6 +944,14 @@ assert('Hash#rehash') do
h = {}
assert_same(h, h.rehash)
assert_predicate(h, :empty?)
+
+ h = {}
+ (1..17).each{h[_1] = _1 * 2}
+ (2..16).each{h.delete(_1)}
+ assert_same(h, h.rehash)
+ assert_equal([[1, 2], [17, 34]], h.to_a)
+ assert_equal(2, h.size)
+ [1, 17].each{assert_equal(_1 * 2, h[_1])}
end
assert('#eql? receiver should be specified key') do