[#105450] [Ruby master Feature#18228] Add a `timeout` option to `IO.copy_stream` — "byroot (Jean Boussier)" <noreply@...>
Issue #18228 has been reported by byroot (Jean Boussier).
11 messages
2021/09/27
[ruby-core:105229] [Ruby master Bug#18164] Segfault after spawn when using modified ENV
From:
"jeremyevans0 (Jeremy Evans)" <noreply@...>
Date:
2021-09-13 18:35:13 UTC
List:
ruby-core #105229
Issue #18164 has been updated by jeremyevans0 (Jeremy Evans).
Fryguy (Jason Frey) wrote in #note-3:
> Speculation ahead, but I'm at the point where I don't understand the Ruby C code anymore...but I think what's happening is, roughly:
>
> https://github.com/ruby/ruby/blob/ebad1e829316de48f212cd57f88639fa5ac55ee4/process.c#L2980-L2984
>
> ```ruby
> else {
> envtbl = rb_const_get(rb_cObject, id_ENV);
> envtbl = rb_to_hash_type(envtbl);
> }
> hide_obj(envtbl);
> ```
I agree, that is a bug. It should not be looking for `Object::ENV`, it should be accessing the internal `envtbl` static variable. I'm guessing the reason it doesn't is that `envtbl` is static in `hash.c`. We probably need to add a non-static function in `hash.c` to return `envtbl` as a hash (e.g. `rb_env_to_hash`), and have the `process.c` code call that.
----------------------------------------
Bug #18164: Segfault after spawn when using modified ENV
https://bugs.ruby-lang.org/issues/18164#change-93635
* Author: Fryguy (Jason Frey)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
* Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
The attached segfault.rb causes a segfault on Ruby 3.0.2 (also on 2.7.2+). This is the smallest reproducer we could get.
```ruby
ENV = {}
spawn({}, "true")
ENV.replace({})
```
You can also change the last line to `ENV.to_s` and it also segfaults.
Note that while this script is the smallest reproducer we could get to, it's unlikely that someone might replace the ENV in this way directly. A more realistic usage scenario (which is how I found this) is using RSpec, having a spec that spawns a subprocess, using `stub_const` to have an alternate ENV, and using `Bundler.with_unbundled_env` to ensure that bundler env vars are not passed to the child process. This is demonstrated in the attached segfault_spec.rb. Here, `stub_const` effectively does the `ENV = {}` portion, and `Bundler.with_unbundled_env` does the `ENV.replace({})` portion (https://github.com/rubygems/rubygems/blob/b737e1c930aaca15618c702f10553992087e2bc4/bundler/lib/bundler.rb#L693)
---Files--------------------------------
segfault.rb (43 Bytes)
segfault_spec.rb (255 Bytes)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>