From: "coldnebo (Larry Kyrala)" Date: 2012-03-30T00:10:20+09:00 Subject: [ruby-core:43871] [ruby-trunk - Bug #6168] Segfault in OpenSSL bindings Issue #6168 has been updated by coldnebo (Larry Kyrala). Cool. Both of our segfault locations in ruby code suggest some kind of buffer sizing problem (mine segs on read, yours on write). Looking at the two locations where the segfault occurs: /local/rvm/rubies/ruby-1.9.2-p318/lib/ruby/1.9.1/openssl/buffering.rb line 38: def fill_rbuff begin => @rbuffer << self.sysread(BLOCK_SIZE) rescue Errno::EAGAIN retry rescue EOFError =* @eof = true end end line 318: def print(*args) s = "" args.each{ |arg| s << arg.to_s } =* do_write(s) nil end In my experience, there are many things that can potentially screw with buffers passed back and forth between ruby and native C. Some things that come to mind: who owns the buffers (ruby or C?) here. Are they padded? (on different architectures?) If there is a choice between calculating the buffer size (via ruby) and getting the return buffer size from libssl, it's better to ask libssl (as crypto buffers vary by implementation and encoding and will most likely differ from ruby's assumptions). Another strategy may be to copy the unencoded buffer from openssl native to ruby before passing it back to be used in ruby string operations or vice versa. There were a lot of changes in 1.9 dealing with byte size and encodings that may have invalidated some edge-case assumptions in the openssl binding that are rather *ahem* hard to test and reproduce. ---------------------------------------- Bug #6168: Segfault in OpenSSL bindings https://bugs.ruby-lang.org/issues/6168#change-25377 Author: amasal (Nguma Abojo) Status: Assigned Priority: Normal Assignee: MartinBosslet (Martin Bosslet) Category: ext Target version: 1.9.3 ruby -v: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux] Hello, A few days ago I updated my Arch Linux server to OpenSSL 1.0.1-1 and Ruby 1.9.3_p125-2. Since then I have been experiencing an odd service failure where a Ruby TLS service of mine would disconnect users with "invalid MAC" exceptions. Shortly after or even before that exception occurs, it segfaults in openssl/buffering.rb. I am not entirely sure whether this is a Ruby OpenSSL bindings bug or even an OpenSSL bug or simply a user error. This is what it prints: /usr/lib/ruby/1.9.1/openssl/buffering.rb:318: [BUG] Segmentation fault ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux] -- Control frame information ----------------------------------------------- c:0016 p:---- s:0081 b:0081 l:000080 d:000080 CFUNC :syswrite c:0015 p:0181 s:0077 b:0077 l:000076 d:000076 METHOD /usr/lib/ruby/1.9.1/openssl/buffering.rb:318 c:0014 p:0030 s:0068 b:0068 l:000067 d:000067 METHOD /usr/lib/ruby/1.9.1/openssl/buffering.rb:415 c:0013 p:0046 s:0063 b:0063 l:000062 d:000062 METHOD /usr/lib/ruby/1.9.1/nil/communication.rb:87 c:0012 p:0011 s:0057 b:0057 l:000051 d:000056 BLOCK /home/void/code/warehouse/notification/NotificationClient.rb:29 c:0011 p:0019 s:0055 b:0055 l:000054 d:000054 METHOD :10 c:0010 p:0013 s:0052 b:0052 l:000051 d:000051 METHOD /home/void/code/warehouse/notification/NotificationClient.rb:29 c:0009 p:0088 s:0048 b:0048 l:000047 d:000047 METHOD /home/void/code/warehouse/notification/NotificationServer.rb:200 c:0008 p:---- s:0039 b:0039 l:000038 d:000038 FINISH c:0007 p:---- s:0037 b:0037 l:000036 d:000036 CFUNC :call c:0006 p:0218 s:0032 b:0032 l:000031 d:000031 METHOD /home/void/code/warehouse/notification /NotificationServer.rb:185 c:0005 p:0146 s:0023 b:0023 l:000022 d:000022 METHOD /home/void/code/warehouse/notification /NotificationServer.rb:162 c:0004 p:0171 s:0014 b:0014 l:000013 d:000013 METHOD /home/void/code/warehouse/notification /NotificationServer.rb:139 c:0003 p:0012 s:0006 b:0006 l:000118 d:000005 BLOCK /home/void/code/warehouse/notification /NotificationServer.rb:102 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:---- s:0002 b:0002 l:000001 d:000001 TOP -- Ruby level backtrace information ---------------------------------------- /home/void/code/warehouse/notification/NotificationServer.rb:102:in `block in runServer' /home/void/code/warehouse/notification/NotificationServer.rb:139:in `handleClient' /home/void/code/warehouse/notification/NotificationServer.rb:162:in `processClientCommunication' /home/void/code/warehouse/notification/NotificationServer.rb:185:in `processClientInput' /home/void/code/warehouse/notification/NotificationServer.rb:185:in `call' /home/void/code/warehouse/notification/NotificationServer.rb:200:in `rpcHandler' /home/void/code/warehouse/notification/NotificationClient.rb:29:in `sendData' :10:in `synchronize' /home/void/code/warehouse/notification/NotificationClient.rb:29:in `block in sendData' /usr/lib/ruby/1.9.1/nil/communication.rb:87:in `sendData' /usr/lib/ruby/1.9.1/openssl/buffering.rb:415:in `print' /usr/lib/ruby/1.9.1/openssl/buffering.rb:318:in `do_write' /usr/lib/ruby/1.9.1/openssl/buffering.rb:318:in `syswrite' -- C level backtrace information ------------------------------------------- /usr/lib/libruby.so.1.9(+0x158ee9) [0x7f3aa715fee9] /usr/lib/libruby.so.1.9(+0x59f99) [0x7f3aa7060f99] /usr/lib/libruby.so.1.9(rb_bug+0xb7) [0x7f3aa70619c7] /usr/lib/libruby.so.1.9(+0xf945f) [0x7f3aa710045f] /lib/libc.so.6(+0x349f0) [0x7f3aa6c9a9f0] /usr/lib/libcrypto.so.1.0.0(RC4+0x431) [0x7f3aa4db6c31] -- http://bugs.ruby-lang.org/