From: "shioimm (Misaki Shioi) via ruby-core" Date: 2024-12-12T14:01:08+00:00 Subject: [ruby-core:120218] [Ruby master Bug#20932] Socket fast_fallback segfaults when fds are > FD_SETSIZE Issue #20932 has been updated by shioimm (Misaki Shioi). Status changed from Assigned to Closed I believe this issue has been resolved with this PR: https://github.com/ruby/ruby/pull/12292. If you have any concerns, please let me know. Thank you again for reporting it. ---------------------------------------- Bug #20932: Socket fast_fallback segfaults when fds are > FD_SETSIZE https://bugs.ruby-lang.org/issues/20932#change-110982 * Author: jhawthorn (John Hawthorn) * Status: Closed * Assignee: shioimm (Misaki Shioi) * Target version: 3.4 * ruby -v: ruby 3.4.0dev (2024-12-04T21:46:02Z master bf225feb26) +PRISM [x86_64-linux] * Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED ---------------------------------------- When `Socket.tcp_fast_fallback = true` and a socket ends up with an FD over FD_SETSIZE (typically 1024), it results in a buffer overflow and crashes when running FD_SET before select. It may be necessary to update ulimits to be above 1024 before reproducing (`ulimit -n 2048`) ``` require "socket" open_fds = [] loop do file = open(__FILE__) open_fds << file break if file.fileno >= 1010 end #Socket.tcp_fast_fallback=false TCPServer.open("localhost", 0) do |server| port = server.addr[1] sockets = [] 50.times do |i| socket = TCPSocket.open("localhost", port) p socket sockets << socket end end ``` ``` $ ulimit -n 2048 $ ruby test.rb # # # # # # # # # # ================================================================= ==3180778==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ae35aadc580 at pc 0x7ae35b1b7449 bp 0x7fffc9af1af0 sp 0x7fffc9af1ae8 READ of size 8 at 0x7ae35aadc580 thread T0 #0 0x7ae35b1b7448 in init_fast_fallback_inetsock_internal /home/jhawthorn/src/ruby/ext/socket/ipsocket.c:912:17 #1 0x60462ff14879 in rb_ensure /home/jhawthorn/src/ruby/eval.c:1053:18 #2 0x7ae35b1b41b9 in rsock_init_inetsock /home/jhawthorn/src/ruby/ext/socket/ipsocket.c:1315:20 #3 0x7ae35b1bae9a in tcp_init /home/jhawthorn/src/ruby/ext/socket/tcpsocket.c:91:12 #4 0x604630178944 in vm_call0_cfunc_with_frame /home/jhawthorn/src/ruby/./vm_eval.c:164:15 #5 0x604630176ade in vm_call0_body /home/jhawthorn/src/ruby/./vm_eval.c:229:15 #6 0x604630146e46 in vm_call0_cc /home/jhawthorn/src/ruby/./vm_eval.c:101:12 #7 0x604630178ffd in rb_call0 /home/jhawthorn/src/ruby/./vm_eval.c:554:12 #8 0x604630147e3a in rb_call /home/jhawthorn/src/ruby/./vm_eval.c:873:12 #9 0x60462ffe15cd in rb_class_new_instance_kw /home/jhawthorn/src/ruby/object.c:2187:5 #10 0x60462ff6c39c in rb_io_s_open /home/jhawthorn/src/ruby/io.c:8126:16 #11 0x604630166e9c in vm_call_cfunc_with_frame_ /home/jhawthorn/src/ruby/./vm_insnhelper.c:3801:11 #12 0x604630134dad in vm_sendish /home/jhawthorn/src/ruby/./vm_insnhelper.c #13 0x60463013c68b in vm_exec_core /home/jhawthorn/src/ruby/insns.def:898:11 #14 0x604630135327 in rb_vm_exec /home/jhawthorn/src/ruby/vm.c:2585:22 #15 0x60463017ba7c in invoke_iseq_block_from_c /home/jhawthorn/src/ruby/vm.c:1615:12 #16 0x60463017ba7c in invoke_block_from_c_bh /home/jhawthorn/src/ruby/vm.c:1629:20 #17 0x60463014b477 in vm_yield_with_cref /home/jhawthorn/src/ruby/vm.c:1666:12 #18 0x604630148937 in rb_yield /home/jhawthorn/src/ruby/./vm_eval.c #19 0x60462ff14879 in rb_ensure /home/jhawthorn/src/ruby/eval.c:1053:18 #20 0x604630166e9c in vm_call_cfunc_with_frame_ /home/jhawthorn/src/ruby/./vm_insnhelper.c:3801:11 #21 0x604630159de6 in vm_call_method_each_type /home/jhawthorn/src/ruby/./vm_insnhelper.c:4779:16 #22 0x604630159afe in vm_call_method /home/jhawthorn/src/ruby/./vm_insnhelper.c #23 0x604630134dad in vm_sendish /home/jhawthorn/src/ruby/./vm_insnhelper.c #24 0x60463013ba52 in vm_exec_core /home/jhawthorn/src/ruby/insns.def:851:11 #25 0x60463015113b in vm_exec_loop /home/jhawthorn/src/ruby/vm.c:2612:22 #26 0x60463013533a in rb_vm_exec /home/jhawthorn/src/ruby/vm.c #27 0x60462ff12f0c in rb_ec_exec_node /home/jhawthorn/src/ruby/eval.c:281:9 #28 0x60462ff12d12 in ruby_run_node /home/jhawthorn/src/ruby/eval.c:319:30 #29 0x60462ff0ed73 in rb_main /home/jhawthorn/src/ruby/./main.c:43:12 #30 0x60462ff0ec47 in main /home/jhawthorn/src/ruby/./main.c:68:12 #31 0x7ae35c5e7e07 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #32 0x7ae35c5e7ecb in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3 #33 0x60462fe2f334 in _start (/home/jhawthorn/.rubies/ruby-asan/bin/ruby+0x174334) Address 0x7ae35aadc580 is located in stack of thread T0 at offset 384 in frame #0 0x7ae35b1b44df in init_fast_fallback_inetsock_internal /home/jhawthorn/src/ruby/ext/socket/ipsocket.c:537 This frame has 14 object(s): [32, 36) 'status' (line 544) [48, 50) 'resolved_type' (line 555) [64, 72) 'pipefd' (line 558) [96, 224) 'readfds' (line 559) [256, 384) 'writefds' (line 559) <== Memory access at offset 384 overflows this variable [416, 456) 'wait_arg' (line 561) [496, 512) 'delay' (line 563) [528, 568) 'resolution_store' (line 567) [608, 624) 'resolution_delay_storage' (line 604) [640, 656) 'connection_attempt_delay_strage' (line 606) [672, 688) 'user_specified_resolv_timeout_storage' (line 608) [704, 720) 'user_specified_connect_timeout_storage' (line 610) [736, 740) 'err' (line 953) [752, 756) 'len' (line 954) HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /home/jhawthorn/src/ruby/ext/socket/ipsocket.c:912:17 in init_fast_fallback_inetsock_internal Shadow bytes around the buggy address: 0x7ae35aadc300: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 0x7ae35aadc380: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 0x7ae35aadc400: f1 f1 f1 f1 04 f2 02 f2 00 f2 f2 f2 00 00 00 00 0x7ae35aadc480: 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2 0x7ae35aadc500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7ae35aadc580:[f2]f2 f2 f2 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 0x7ae35aadc600: f2 f2 00 00 00 00 00 f2 f2 f2 f2 f2 00 00 f2 f2 0x7ae35aadc680: 00 00 f2 f2 00 00 f2 f2 00 00 f2 f2 f8 f2 f8 f3 0x7ae35aadc700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ae35aadc780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7ae35aadc800: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==3180778==ABORTING ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/