<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/ext/socket/ipsocket.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>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>Ensure that memory is not freed before calling `free_fast_fallback_getaddrinfo_*` (#12661)</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-01-29T13:19:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=584365af7baeb80b74d31a26b8ec51e66b2ccc1a'/>
<id>584365af7baeb80b74d31a26b8ec51e66b2ccc1a</id>
<content type='text'>
Ensure that `getaddrinfo_entry` and `getaddrinfo_shared` exist before free them in the main thread.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Ensure that `getaddrinfo_entry` and `getaddrinfo_shared` exist before free them in the main thread.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix crash in TCPSocket.open</title>
<updated>2025-04-09T23:02:37+00:00</updated>
<author>
<name>Luke Jahnke</name>
<email>luke.jahnke@gmail.com</email>
</author>
<published>2025-03-14T13:38:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7e093fb43a692935823de1bb32ac4f05e46329bb'/>
<id>7e093fb43a692935823de1bb32ac4f05e46329bb</id>
<content type='text'>
Fix segfault crash observable with TCPSocket.open(nil, nil)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix segfault crash observable with TCPSocket.open(nil, nil)
</pre>
</div>
</content>
</entry>
<entry>
<title>merge revision(s) 1683dadb19876f0a64589bdbbcf6fff8143f78ff: [Backport #21088]</title>
<updated>2025-02-14T05:13:47+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2025-02-14T05:13:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=319c3c70385a63aaea3c1a68a79c70cfd533c6b6'/>
<id>319c3c70385a63aaea3c1a68a79c70cfd533c6b6</id>
<content type='text'>
	Do not save ResolutionError if resolution succeeds for any address family (#12678)

	* Do not save ResolutionError if resolution succeeds for any address family

	Socket with Happy Eyeballs Version 2 performs connection attempts and name resolution in parallel.

	In the existing implementation, if a connection attempt failed for one address family while name resolution was still in progress for the other, and that name resolution later failed, the method would terminate with a name resolution error.
	This behavior was intended to ensure that the final error reflected the most recent failure, potentially overriding an earlier error.

	However, [Bug #21088](https://bugs.ruby-lang.org/issues/21088) made me realize that terminating with a name resolution error is unnatural when name resolution succeeded for at least one address family.

	This PR modifies the behavior so that if name resolution succeeds for one address family, any name resolution error from the other is not saved.

	This PR includes the following changes:

	* Do not display select(2) as the system call that caused the raised error, as it is for internal processing

	* Fix bug: Get errno with Socket::SO_ERROR in Windows environment with a workaround for tests not passing
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	Do not save ResolutionError if resolution succeeds for any address family (#12678)

	* Do not save ResolutionError if resolution succeeds for any address family

	Socket with Happy Eyeballs Version 2 performs connection attempts and name resolution in parallel.

	In the existing implementation, if a connection attempt failed for one address family while name resolution was still in progress for the other, and that name resolution later failed, the method would terminate with a name resolution error.
	This behavior was intended to ensure that the final error reflected the most recent failure, potentially overriding an earlier error.

	However, [Bug #21088](https://bugs.ruby-lang.org/issues/21088) made me realize that terminating with a name resolution error is unnatural when name resolution succeeded for at least one address family.

	This PR modifies the behavior so that if name resolution succeeds for one address family, any name resolution error from the other is not saved.

	This PR includes the following changes:

	* Do not display select(2) as the system call that caused the raised error, as it is for internal processing

	* Fix bug: Get errno with Socket::SO_ERROR in Windows environment with a workaround for tests not passing
</pre>
</div>
</content>
</entry>
<entry>
<title>Introduce a timeout to prevent `rb_thread_fd_select` from hanging with write(2) failure (#12457)</title>
<updated>2024-12-24T18:06:02+00:00</updated>
<author>
<name>Misaki Shioi</name>
<email>31817032+shioimm@users.noreply.github.com</email>
</author>
<published>2024-12-24T18:06:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=3be1baab82d8627ce52391030160bcbca69db01d'/>
<id>3be1baab82d8627ce52391030160bcbca69db01d</id>
<content type='text'>
Rarely, there are cases where a write(2) call from a child thread
to notify the main thread of the completion of name resolution fails.
If this happens while the main thread is waiting in `rb_thread_fd_select`,
rb_thread_fd_select may not notice that the name resolution has completed and end up hanging.

This issue becomes a problem when there are no sockets currently being connected,
no addresses ready for immediate connection attempts,
and name resolution has already completed for one address family
while the main thread is waiting for the name resolution of the other address family.
(If name resolution is not completed for either address family,
the chances of write(2) failing in both child threads are likely low.)

To avoid this issue, a timeout is introduced to rb_thread_fd_select under the above conditions.
This way, even if the issue occurs,
the completion of name resolution should still be detected
in the subsequent `if (!resolution_store.is_all_finished) ...` block.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Rarely, there are cases where a write(2) call from a child thread
to notify the main thread of the completion of name resolution fails.
If this happens while the main thread is waiting in `rb_thread_fd_select`,
rb_thread_fd_select may not notice that the name resolution has completed and end up hanging.

This issue becomes a problem when there are no sockets currently being connected,
no addresses ready for immediate connection attempts,
and name resolution has already completed for one address family
while the main thread is waiting for the name resolution of the other address family.
(If name resolution is not completed for either address family,
the chances of write(2) failing in both child threads are likely low.)

To avoid this issue, a timeout is introduced to rb_thread_fd_select under the above conditions.
This way, even if the issue occurs,
the completion of name resolution should still be detected
in the subsequent `if (!resolution_store.is_all_finished) ...` block.</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>
</feed>
