Bug #3454
closedSegfault with syscall
Description
=begin
IRB segfaults consistently with the following (reduced from something sensible):
buf='';syscall(106,'/etc/passwd',buf)
106 is stat(2) on this system.
/usr/local/lib/ruby/1.9.1/irb/workspace.rb:81: [BUG] Segmentation fault
ruby 1.9.3dev (2010-06-13 trunk 28312) [i686-linux]
-- control frame ----------
c:0022 p:---- s:0081 b:0081 l:000080 d:000080 CFUNC :eval
c:0021 p:0061 s:0074 b:0074 l:000073 d:000073 METHOD /usr/local/lib/ruby/1.9.1/irb/workspace.rb:81
c:0020 p:0023 s:0067 b:0067 l:000066 d:000066 METHOD /usr/local/lib/ruby/1.9.1/irb/context.rb:167
c:0019 p:0039 s:0063 b:0063 l:000062 d:000062 METHOD /usr/local/lib/ruby/1.9.1/irb/context.rb:254
c:0018 p:0031 s:0058 b:0058 l:001e3c d:000057 BLOCK /usr/local/lib/ruby/1.9.1/irb.rb:159
c:0017 p:0042 s:0050 b:0050 l:000049 d:000049 METHOD /usr/local/lib/ruby/1.9.1/irb.rb:273
c:0016 p:0011 s:0045 b:0045 l:001e3c d:000044 BLOCK /usr/local/lib/ruby/1.9.1/irb.rb:156
c:0015 p:0144 s:0041 b:0041 l:000024 d:000040 BLOCK /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:243
c:0014 p:---- s:0038 b:0038 l:000037 d:000037 FINISH
c:0013 p:---- s:0036 b:0036 l:000035 d:000035 CFUNC :loop
c:0012 p:0009 s:0033 b:0033 l:000024 d:000032 BLOCK /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229
c:0011 p:---- s:0031 b:0031 l:000030 d:000030 FINISH
c:0010 p:---- s:0029 b:0029 l:000028 d:000028 CFUNC :catch
c:0009 p:0023 s:0025 b:0025 l:000024 d:000024 METHOD /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:228
c:0008 p:0046 s:0022 b:0022 l:001e3c d:001e3c METHOD /usr/local/lib/ruby/1.9.1/irb.rb:155
c:0007 p:0011 s:0019 b:0019 l:00076c d:000018 BLOCK /usr/local/lib/ruby/1.9.1/irb.rb:70
c:0006 p:---- s:0017 b:0017 l:000016 d:000016 FINISH
c:0005 p:---- s:0015 b:0015 l:000014 d:000014 CFUNC :catch
c:0004 p:0183 s:0011 b:0011 l:00076c d:00076c METHOD /usr/local/lib/ruby/1.9.1/irb.rb:69
c:0003 p:0039 s:0006 b:0006 l:0000dc d:000fb4 EVAL /usr/local/bin/irb:12
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0000dc d:0000dc TOP
-- Ruby level backtrace information ----------------------------------------
/usr/local/bin/irb:12:in <main>' /usr/local/lib/ruby/1.9.1/irb.rb:69:in
start'
/usr/local/lib/ruby/1.9.1/irb.rb:69:in catch' /usr/local/lib/ruby/1.9.1/irb.rb:70:in
block in start'
/usr/local/lib/ruby/1.9.1/irb.rb:155:in eval_input' /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in
each_top_level_statement'
/usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in catch' /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in
block in each_top_level_statement'
/usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in loop' /usr/local/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in
block (2 levels) in each_top_level_statement'
/usr/local/lib/ruby/1.9.1/irb.rb:156:in block in eval_input' /usr/local/lib/ruby/1.9.1/irb.rb:273:in
signal_status'
/usr/local/lib/ruby/1.9.1/irb.rb:159:in block (2 levels) in eval_input' /usr/local/lib/ruby/1.9.1/irb/context.rb:254:in
evaluate'
/usr/local/lib/ruby/1.9.1/irb/context.rb:167:in set_last_value' /usr/local/lib/ruby/1.9.1/irb/workspace.rb:81:in
evaluate'
/usr/local/lib/ruby/1.9.1/irb/workspace.rb:81:in `eval'
-- C level backtrace information -------------------------------------------
irb(rb_vm_bugreport+0xa5) [0x8161e25]
irb() [0x81a0b79]
irb(rb_bug+0x28) [0x81a0c28]
irb() [0x80f41e8]
[0xe35410]
irb() [0x80a0419]
irb(ruby_yyparse+0x36ce) [0x80aa86e]
irb() [0x80b4fa9]
irb(ruby_suppress_tracing+0x103) [0x81632f3]
irb(rb_parser_compile_string+0xa6) [0x80a1266]
irb(rb_iseq_compile_with_option+0x52) [0x814bc52]
irb(rb_iseq_compile+0x2f) [0x814be3f]
irb() [0x815ed1e]
irb(rb_f_eval+0xc7) [0x815f4f7]
irb() [0x814d625]
irb() [0x8158911]
irb() [0x815acb8]
irb() [0x815e696]
irb() [0x816000e]
irb(rb_rescue2+0x141) [0x805e241]
irb() [0x814e544]
irb() [0x8158911]
irb() [0x815acb8]
irb() [0x815e696]
irb() [0x815f82d]
irb(rb_catch_obj+0x9f) [0x814d1cf]
irb() [0x814e3f6]
irb() [0x814d625]
irb() [0x8158911]
irb() [0x815acb8]
irb() [0x815e696]
irb() [0x815f82d]
irb(rb_catch_obj+0x9f) [0x814d1cf]
irb() [0x814e3f6]
irb() [0x814d625]
irb() [0x8158911]
irb() [0x815acb8]
irb() [0x815e696]
irb(rb_iseq_eval_main+0x1c7) [0x815ea67]
irb() [0x805e492]
irb(ruby_run_node+0x32) [0x805fca2]
irb(main+0x5a) [0x805d6ca]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0x37dbd6]
irb() [0x805d5d1]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Aborted
The closest I've come to reproducing outside of IRB is with:
buf=''
GC.stress=true
p syscall(106, '/etc/hosts', buf)
The GC.stress call isn't necessary, but increases the frequency of the crash. The above gives:
[BUG] Segmentation fault
ruby 1.9.3dev (2010-06-13 trunk 28312) [i686-linux]
-- control frame ----------
c:0004 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :p
c:0003 p:0048 s:0007 b:0007 l:000edc d:001908 EVAL seg4.rb:3
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:000edc d:000edc TOP
-- Ruby level backtrace information ----------------------------------------
seg4.rb:3:in <main>' seg4.rb:3:in
p'
-- C level backtrace information -------------------------------------------
ruby(rb_vm_bugreport+0xa5) [0x8161e25]
ruby() [0x81a0b79]
ruby(rb_bug+0x28) [0x81a0c28]
ruby() [0x80f41e8]
[0x63f410]
ruby() [0x8068f68]
ruby(st_foreach+0x9e) [0x80fbf7e]
ruby(rb_mark_tbl+0x3a) [0x8066d0a]
ruby(rb_gc_mark_symbols+0x13) [0x809fbc3]
ruby() [0x80696a8]
ruby() [0x8069ae3]
ruby() [0x8069fad]
ruby() [0x8079c76]
ruby() [0x807a366]
ruby(rb_p+0x162) [0x807a7b2]
ruby() [0x807beb6]
ruby() [0x814d625]
ruby() [0x8158911]
ruby() [0x815acb8]
ruby() [0x815e696]
ruby(rb_iseq_eval_main+0x1c7) [0x815ea67]
ruby() [0x805e492]
ruby(ruby_run_node+0x32) [0x805fca2]
ruby(main+0x5a) [0x805d6ca]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0xc84bd6]
ruby() [0x805d5d1]
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Aborted
On another run of a similar script, without GC.stress, I got:
*** glibc detected *** ruby: free(): invalid next size (normal): 0x097d00d0 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x17b591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x17cde8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x17fecd]
ruby(rb_objspace_free+0x7c)[0x806792c]
ruby(ruby_vm_destruct+0xcf)[0x815150f]
ruby(ruby_cleanup+0x1df)[0x805facf]
ruby(ruby_run_node+0x3a)[0x805fcaa]
ruby(main+0x5a)[0x805d6ca]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x126bd6]
ruby[0x805d5d1]
======= Memory map: ========
00110000-00263000 r-xp 00000000 08:01 266196 /lib/tls/i686/cmov/libc-2.11.1.so
00263000-00264000 ---p 00153000 08:01 266196 /lib/tls/i686/cmov/libc-2.11.1.so
00264000-00266000 r--p 00153000 08:01 266196 /lib/tls/i686/cmov/libc-2.11.1.so
00266000-00267000 rw-p 00155000 08:01 266196 /lib/tls/i686/cmov/libc-2.11.1.so
00267000-0026a000 rw-p 00000000 00:00 0
0026a000-00287000 r-xp 00000000 08:01 678 /lib/libgcc_s.so.1
00287000-00288000 r--p 0001c000 08:01 678 /lib/libgcc_s.so.1
00288000-00289000 rw-p 0001d000 08:01 678 /lib/libgcc_s.so.1
00440000-00442000 r-xp 00000000 08:01 289176 /usr/local/lib/ruby/1.9.1/i686-linux/enc/trans/transdb.so
00442000-00443000 r--p 00001000 08:01 289176 /usr/local/lib/ruby/1.9.1/i686-linux/enc/trans/transdb.so
00443000-00444000 rw-p 00002000 08:01 289176 /usr/local/lib/ruby/1.9.1/i686-linux/enc/trans/transdb.so
0046d000-00474000 r-xp 00000000 08:01 312382 /lib/tls/i686/cmov/librt-2.11.1.so
00474000-00475000 r--p 00006000 08:01 312382 /lib/tls/i686/cmov/librt-2.11.1.so
00475000-00476000 rw-p 00007000 08:01 312382 /lib/tls/i686/cmov/librt-2.11.1.so
00bbd000-00bbf000 r-xp 00000000 08:01 270954 /usr/local/lib/ruby/1.9.1/i686-linux/enc/encdb.so
00bbf000-00bc0000 r--p 00001000 08:01 270954 /usr/local/lib/ruby/1.9.1/i686-linux/enc/encdb.so
00bc0000-00bc1000 rw-p 00002000 08:01 270954 /usr/local/lib/ruby/1.9.1/i686-linux/enc/encdb.so
00c76000-00c7f000 r-xp 00000000 08:01 276341 /lib/tls/i686/cmov/libcrypt-2.11.1.so
00c7f000-00c80000 r--p 00008000 08:01 276341 /lib/tls/i686/cmov/libcrypt-2.11.1.so
00c80000-00c81000 rw-p 00009000 08:01 276341 /lib/tls/i686/cmov/libcrypt-2.11.1.so
00c81000-00ca8000 rw-p 00000000 00:00 0
00db6000-00dda000 r-xp 00000000 08:01 276343 /lib/tls/i686/cmov/libm-2.11.1.so
00dda000-00ddb000 r--p 00023000 08:01 276343 /lib/tls/i686/cmov/libm-2.11.1.so
00ddb000-00ddc000 rw-p 00024000 08:01 276343 /lib/tls/i686/cmov/libm-2.11.1.so
00e25000-00e27000 r-xp 00000000 08:01 276342 /lib/tls/i686/cmov/libdl-2.11.1.so
00e27000-00e28000 r--p 00001000 08:01 276342 /lib/tls/i686/cmov/libdl-2.11.1.so
00e28000-00e29000 rw-p 00002000 08:01 276342 /lib/tls/i686/cmov/libdl-2.11.1.so
00e2c000-00e47000 r-xp 00000000 08:01 44106 /lib/ld-2.11.1.so
00e47000-00e48000 r--p 0001a000 08:01 44106 /lib/ld-2.11.1.so
00e48000-00e49000 rw-p 0001b000 08:01 44106 /lib/ld-2.11.1.so
00e76000-00e77000 r-xp 00000000 00:00 0 [vdso]
00f44000-00f59000 r-xp 00000000 08:01 312380 /lib/tls/i686/cmov/libpthread-2.11.1.so
00f59000-00f5a000 r--p 00014000 08:01 312380 /lib/tls/i686/cmov/libpthread-2.11.1.so
00f5a000-00f5b000 rw-p 00015000 08:01 312380 /lib/tls/i686/cmov/libpthread-2.11.1.so
00f5b000-00f5d000 rw-p 00000000 00:00 0
08048000-08213000 r-xp 00000000 08:01 262732 /usr/local/bin/ruby
08213000-08214000 r--p 001ca000 08:01 262732 /usr/local/bin/ruby
08214000-08215000 rw-p 001cb000 08:01 262732 /usr/local/bin/ruby
08215000-08222000 rw-p 00000000 00:00 0
097bd000-0989f000 rw-p 00000000 00:00 0 [heap]
b7700000-b7721000 rw-p 00000000 00:00 0
b7721000-b7800000 ---p 00000000 00:00 0
b785d000-b789c000 r--p 00000000 08:01 613559 /usr/lib/locale/en_GB.utf8/LC_CTYPE
b789c000-b789f000 rw-p 00000000 00:00 0
b78ab000-b78ac000 ---p 00000000 00:00 0
b78ac000-b78af000 rw-p 00000000 00:00 0
b78af000-b78b6000 r--s 00000000 08:01 427947 /usr/lib/gconv/gconv-modules.cache
b78b6000-b78b8000 rw-p 00000000 00:00 0
bfa07000-bfa1c000 rw-p 00000000 00:00 0 [stack]
Command terminated
=end
Updated by shyouhei (Shyouhei Urabe) over 14 years ago
=begin
Ruby does not stop you to shoot your foot. I believe this is not a bug.
=end
Updated by matz (Yukihiro Matsumoto) over 14 years ago
=begin
Hi,
In message "Re: [ruby-core:30824] [Bug #3454] Segfault with syscall"
on Sat, 19 Jun 2010 21:04:16 +0900, Shyouhei Urabe redmine@ruby-lang.org writes:
|Issue #3454 has been updated by Shyouhei Urabe.
|
|Ruby does not stop you to shoot your foot. I believe this is not a bug.
Indeed. syscall expected buffer of sizeof(struct stat), but you gave
it an empty string, so as natural consequence syscall overwrote memory
region, and segmentation fault was happened. When you use syscall,
it's fundamentally C programming with Ruby syntax, so you can do
anything as bad as C can. Same rule applied to dl and ffi.
I will restrict syscall to require $SAFE=0, just for fool proof.
matz.
=end
Updated by matz (Yukihiro Matsumoto) over 14 years ago
=begin
Hi,
In message "Re: [ruby-core:30826] Re: [Bug #3454] Segfault with syscall"
on Sun, 20 Jun 2010 00:01:32 +0900, Yukihiro Matsumoto matz@ruby-lang.org writes:
|I will restrict syscall to require $SAFE=0, just for fool proof.
Oops, it has already restricted to $SAFE<2.
matz.
=end
Updated by shyouhei (Shyouhei Urabe) over 14 years ago
- Status changed from Open to Rejected
=begin
=end