<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/ext/socket/raddrinfo.c, branch v3_4_9</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Avoid spawning thread for trivial getnameinfo calls</title>
<updated>2025-11-17T21:28:01+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2025-08-20T02:13:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7482835d0b5c9f55662fb7c6586f456354e2b66e'/>
<id>7482835d0b5c9f55662fb7c6586f456354e2b66e</id>
<content type='text'>
When calling getnameinfo we spawn a thread because it may do a slow,
blocking reverse-DNS lookup. Spawning a thread is relatively fast (~20µs
on my Linux machine) but still an order of magnitude slower than when
getnameinfo is simply translating to a numeric IP or port, which, at
least in my tests on Linux, doesn't even make a syscall.

This commit adds a fast path for when reverse DNS isn't required: either
host isn't being fetched or NI_NUMERICHOST is set AND either the
service name isn't required or NI_NUMERICSERV is set. The service name
should only need to read /etc/services, which should be fast-ish, but
is still I/O so I kept the existing behaviour (it could be on a network
fs I guess).

I tested with:

    s = TCPSocket.open("www.ruby-lang.org", 80)
    500_000.times { Socket.unpack_sockaddr_in(s.getpeername) }

Before: 12.935s
After: 0.338s
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When calling getnameinfo we spawn a thread because it may do a slow,
blocking reverse-DNS lookup. Spawning a thread is relatively fast (~20µs
on my Linux machine) but still an order of magnitude slower than when
getnameinfo is simply translating to a numeric IP or port, which, at
least in my tests on Linux, doesn't even make a syscall.

This commit adds a fast path for when reverse DNS isn't required: either
host isn't being fetched or NI_NUMERICHOST is set AND either the
service name isn't required or NI_NUMERICSERV is set. The service name
should only need to read /etc/services, which should be fast-ish, but
is still I/O so I kept the existing behaviour (it could be on a network
fs I guess).

I tested with:

    s = TCPSocket.open("www.ruby-lang.org", 80)
    500_000.times { Socket.unpack_sockaddr_in(s.getpeername) }

Before: 12.935s
After: 0.338s
</pre>
</div>
</content>
</entry>
<entry>
<title>ext/socket: Set raddrinfo thread as detached before thread start (#15194)</title>
<updated>2025-11-14T19:48:40+00:00</updated>
<author>
<name>Luke Gruber</name>
<email>luke.gruber@shopify.com</email>
</author>
<published>2025-11-14T19:48:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=9e4829699b544370dd3a83df3e2c6b9168c34159'/>
<id>9e4829699b544370dd3a83df3e2c6b9168c34159</id>
<content type='text'>
Backport of https://github.com/ruby/ruby/pull/15142

[Bug #21679]</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Backport of https://github.com/ruby/ruby/pull/15142

[Bug #21679]</pre>
</div>
</content>
</entry>
<entry>
<title>Fix `heap-use-after-free` in `free_fast_fallback_getaddrinfo_entry` (#13231)</title>
<updated>2025-06-18T18:09:20+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2025-05-03T12:39:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c57efbfb3ac3848f954735600bbab1ea814dd742'/>
<id>c57efbfb3ac3848f954735600bbab1ea814dd742</id>
<content type='text'>
This change addresses the following ASAN error:

```
==36597==ERROR: AddressSanitizer: heap-use-after-free on address 0x512000396ba8 at pc 0x7fcad5cbad9f bp 0x7fff19739af0 sp 0x7fff19739ae8
  WRITE of size 8 at 0x512000396ba8 thread T0
  [643/756] 36600=optparse/test_summary
      #0 0x7fcad5cbad9e in free_fast_fallback_getaddrinfo_entry /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/raddrinfo.c:3046:22
      #1 0x7fcad5c9fb48 in fast_fallback_inetsock_cleanup /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/ipsocket.c:1179:17
      #2 0x7fcadf3b611a in rb_ensure /home/runner/work/ruby-dev-builder/ruby-dev-builder/eval.c:1081:5
      #3 0x7fcad5c9b44b in rsock_init_inetsock /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/ipsocket.c:1289:20
      #4 0x7fcad5ca22b8 in tcp_init /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/tcpsocket.c:76:12
      #5 0x7fcadf83ba70 in vm_call0_cfunc_with_frame /home/runner/work/ruby-dev-builder/ruby-dev-builder/./vm_eval.c:164:15
...
```

A `struct fast_fallback_getaddrinfo_shared` is shared between the main thread and two child threads.
This struct contains an array of `fast_fallback_getaddrinfo_entry`.

`fast_fallback_getaddrinfo_entry` and `fast_fallback_getaddrinfo_shared` were freed separately, and if `fast_fallback_getaddrinfo_shared` was freed first and then an attempt was made to free a `fast_fallback_getaddrinfo_entry`, a `heap-use-after-free` could occur.

This change avoids that possibility by separating the deallocation of the addrinfo memory held by `fast_fallback_getaddrinfo_entry` from the access and lifecycle of the `fast_fallback_getaddrinfo_entry` itself.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change addresses the following ASAN error:

```
==36597==ERROR: AddressSanitizer: heap-use-after-free on address 0x512000396ba8 at pc 0x7fcad5cbad9f bp 0x7fff19739af0 sp 0x7fff19739ae8
  WRITE of size 8 at 0x512000396ba8 thread T0
  [643/756] 36600=optparse/test_summary
      #0 0x7fcad5cbad9e in free_fast_fallback_getaddrinfo_entry /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/raddrinfo.c:3046:22
      #1 0x7fcad5c9fb48 in fast_fallback_inetsock_cleanup /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/ipsocket.c:1179:17
      #2 0x7fcadf3b611a in rb_ensure /home/runner/work/ruby-dev-builder/ruby-dev-builder/eval.c:1081:5
      #3 0x7fcad5c9b44b in rsock_init_inetsock /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/ipsocket.c:1289:20
      #4 0x7fcad5ca22b8 in tcp_init /home/runner/work/ruby-dev-builder/ruby-dev-builder/ext/socket/tcpsocket.c:76:12
      #5 0x7fcadf83ba70 in vm_call0_cfunc_with_frame /home/runner/work/ruby-dev-builder/ruby-dev-builder/./vm_eval.c:164:15
...
```

A `struct fast_fallback_getaddrinfo_shared` is shared between the main thread and two child threads.
This struct contains an array of `fast_fallback_getaddrinfo_entry`.

`fast_fallback_getaddrinfo_entry` and `fast_fallback_getaddrinfo_shared` were freed separately, and if `fast_fallback_getaddrinfo_shared` was freed first and then an attempt was made to free a `fast_fallback_getaddrinfo_entry`, a `heap-use-after-free` could occur.

This change avoids that possibility by separating the deallocation of the addrinfo memory held by `fast_fallback_getaddrinfo_entry` from the access and lifecycle of the `fast_fallback_getaddrinfo_entry` itself.</pre>
</div>
</content>
</entry>
<entry>
<title>Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork` (#12366)</title>
<updated>2024-12-18T00:48:26+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-18T00:48:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=498d6eb114c52bd16a6821029959e88ed8f87396'/>
<id>498d6eb114c52bd16a6821029959e88ed8f87396</id>
<content type='text'>
Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork`

Referencing PR #10864,
wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork`
to avoid fork safety issues.

`do_fast_fallback_getaddrinfo` internally uses getaddrinfo(3),
leading to fork safety issues, as described in PR #10864.
This change ensures that `do_fast_fallback_getaddrinfo`
is guarded by `rb_thread_prevent_fork`,
preventing fork during its execution and avoiding related issues.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork`

Referencing PR #10864,
wrap `do_fast_fallback_getaddrinfo` with `rb_thread_prevent_fork`
to avoid fork safety issues.

`do_fast_fallback_getaddrinfo` internally uses getaddrinfo(3),
leading to fork safety issues, as described in PR #10864.
This change ensures that `do_fast_fallback_getaddrinfo`
is guarded by `rb_thread_prevent_fork`,
preventing fork during its execution and avoiding related issues.</pre>
</div>
</content>
</entry>
<entry>
<title>Use ruby_strdup/xfree in fast_fallback</title>
<updated>2024-12-11T23:37:32+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2024-12-11T22:44:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d84859061a39b81b85bdbae8cfff5088a5c78a93'/>
<id>d84859061a39b81b85bdbae8cfff5088a5c78a93</id>
<content type='text'>
Any memory allocated with xmalloc needs to be matched with xfree rather
than plain free.

Ruby unfortunately redefines strdup to be ruby_strdup, which uses
xmalloc so needs to be xfreed. Previously these were mismatched.

This commit changes the copy to be an explicit ruby_strdup (to avoid
confusion) and the free to be xfree.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Any memory allocated with xmalloc needs to be matched with xfree rather
than plain free.

Ruby unfortunately redefines strdup to be ruby_strdup, which uses
xmalloc so needs to be xfreed. Previously these were mismatched.

This commit changes the copy to be an explicit ruby_strdup (to avoid
confusion) and the free to be xfree.
</pre>
</div>
</content>
</entry>
<entry>
<title>Use `rb_thread_fd_select` instead of select(2) (#12292)</title>
<updated>2024-12-11T09:57:23+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-11T09:57:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f9601903f64e56d95c140074980584c09373b040'/>
<id>f9601903f64e56d95c140074980584c09373b040</id>
<content type='text'>
* Use `rb_thread_fd_select` instead of select(2)

For fixing https://bugs.ruby-lang.org/issues/20932 .
`TCPSocket.new`, which internally uses select(2) for HEv2, can cause SEGV if the number of file descriptors exceeds `FD_SETSIZE`.
This change avoids that issue by replacing select(2) with `rb_thread_fd_select`, which is provided as part of Ruby's internal API.

---

This includes the following changes.

* rb_thread_fd_select does not need common pipe</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Use `rb_thread_fd_select` instead of select(2)

For fixing https://bugs.ruby-lang.org/issues/20932 .
`TCPSocket.new`, which internally uses select(2) for HEv2, can cause SEGV if the number of file descriptors exceeds `FD_SETSIZE`.
This change avoids that issue by replacing select(2) with `rb_thread_fd_select`, which is provided as part of Ruby's internal API.

---

This includes the following changes.

* rb_thread_fd_select does not need common pipe</pre>
</div>
</content>
</entry>
<entry>
<title>Fix use of getaddrinfo_shared-&gt;lock</title>
<updated>2024-12-03T18:03:59+00:00</updated>
<author>
<name>John Hawthorn</name>
<email>john@hawthorn.email</email>
</author>
<published>2024-12-03T03:41:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e20904d7cff727f14559acd39f5279fed816553d'/>
<id>e20904d7cff727f14559acd39f5279fed816553d</id>
<content type='text'>
In some locations we were using shared-&gt;lock and in others
&amp;shared-&gt;lock, and we were leaking the allocated memory.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In some locations we were using shared-&gt;lock and in others
&amp;shared-&gt;lock, and we were leaking the allocated memory.
</pre>
</div>
</content>
</entry>
<entry>
<title>Ensure to close pipes when `TCPSocket.new` finishes processing (#12181)</title>
<updated>2024-11-29T09:49:02+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-29T09:49:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=49d2e79fb0dd57caed269c67660ff4cc68b3d729'/>
<id>49d2e79fb0dd57caed269c67660ff4cc68b3d729</id>
<content type='text'>
`TCPSocket.new` with HEv2 uses three threads.
The last of these threads to exit closed pipes.
However, if pipes were open at the end of the main thread, they would leak.
This change avoids this by closing pipes at the end of the main thread.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`TCPSocket.new` with HEv2 uses three threads.
The last of these threads to exit closed pipes.
However, if pipes were open at the end of the main thread, they would leak.
This change avoids this by closing pipes at the end of the main thread.</pre>
</div>
</content>
</entry>
<entry>
<title>Prevent memory leak</title>
<updated>2024-11-25T11:18:48+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2024-11-25T09:23:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=92585898fb369c79e7f711465e5934ff4c1879f9'/>
<id>92585898fb369c79e7f711465e5934ff4c1879f9</id>
<content type='text'>
```
for (int i = 0; i &lt; arg-&gt;family_size; i++) {
    arg-&gt;getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();
    if (!(arg-&gt;getaddrinfo_entries[i])) rb_syserr_fail(errno, "calloc(3)");
```

If the allocation fails in the second interation, the memory allocated
in the first iteration would be leaked.

This change prevents the memory leak by allocating the memory in
advance.
(The struct name `fast_fallback_getaddrinfo_shared` might no longer be
good.)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
```
for (int i = 0; i &lt; arg-&gt;family_size; i++) {
    arg-&gt;getaddrinfo_entries[i] = allocate_fast_fallback_getaddrinfo_entry();
    if (!(arg-&gt;getaddrinfo_entries[i])) rb_syserr_fail(errno, "calloc(3)");
```

If the allocation fails in the second interation, the memory allocated
in the first iteration would be leaked.

This change prevents the memory leak by allocating the memory in
advance.
(The struct name `fast_fallback_getaddrinfo_shared` might no longer be
good.)
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix stack-use-after-return (#12105)</title>
<updated>2024-11-17T01:36:33+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-11-17T01:36:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3c30af77fea37a10b95a3fc322ff20d7086cab5f'/>
<id>3c30af77fea37a10b95a3fc322ff20d7086cab5f</id>
<content type='text'>
http://ci.rvm.jp/results/trunk_asan@ruby-sp1/5409001

```
=================================================================
==3263562==ERROR: AddressSanitizer: stack-use-after-return on address 0x735a8f190da8 at pc 0x735a6f58dabc bp 0x735a639ffd10 sp 0x735a639ffd08
READ of size 4 at 0x735a8f190da8 thread T211
=================================================================
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
http://ci.rvm.jp/results/trunk_asan@ruby-sp1/5409001

```
=================================================================
==3263562==ERROR: AddressSanitizer: stack-use-after-return on address 0x735a8f190da8 at pc 0x735a6f58dabc bp 0x735a639ffd10 sp 0x735a639ffd08
READ of size 4 at 0x735a8f190da8 thread T211
=================================================================
```</pre>
</div>
</content>
</entry>
</feed>
