[#90865] [Ruby trunk Bug#15499] Breaking behavior on ruby 2.6: rb_thread_call_without_gvl doesn't invoke unblock_function when used on the main thread — apolcyn@...
Issue #15499 has been reported by apolcyn (alex polcyn).
3 messages
2019/01/03
[#90877] [Ruby trunk Bug#15499] Breaking behavior on ruby 2.6: rb_thread_call_without_gvl doesn't invoke unblock_function when used on the main thread — apolcyn@...
Issue #15499 has been updated by apolcyn (alex polcyn).
3 messages
2019/01/03
[#90895] Re: [ruby-alerts:11680] failure alert on trunk-mjit@silicon-docker (NG (r66707)) — Eric Wong <normalperson@...>
ko1c-failure@atdot.net wrote:
4 messages
2019/01/05
[#90896] Re: [ruby-alerts:11680] failure alert on trunk-mjit@silicon-docker (NG (r66707))
— Takashi Kokubun <takashikkbn@...>
2019/01/05
Thanks to explain that.
[#91200] [Ruby trunk Feature#15553] Addrinfo.getaddrinfo supports timeout — glass.saga@...
Issue #15553 has been reported by Glass_saga (Masaki Matsushita).
4 messages
2019/01/21
[#91289] Re: [Ruby trunk Feature#15553] Addrinfo.getaddrinfo supports timeout
— Eric Wong <normalperson@...>
2019/01/26
glass.saga@gmail.com wrote:
[ruby-core:91216] [Ruby trunk Bug#15555] Dir.mktmpdir checks permissions and raise ArgumentError after yielding to block (ensure) & leaks allocated tempdir
From:
kabogtob@...
Date:
2019-01-22 10:11:33 UTC
List:
ruby-core #91216
Issue #15555 has been reported by kbogtob (Karim Bogtob).
----------------------------------------
Bug #15555: Dir.mktmpdir checks permissions and raise ArgumentError after yielding to block (ensure) & leaks allocated tempdir
https://bugs.ruby-lang.org/issues/15555
* Author: kbogtob (Karim Bogtob)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux-gnu]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
The current implementation of the Dir.mktmpdir is the following:
```ruby
def Dir.mktmpdir(prefix_suffix=nil, *rest)
path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
if block_given?
begin
yield path
ensure
stat = File.stat(File.dirname(path))
if stat.world_writable? and !stat.sticky?
raise ArgumentError, "parent directory is world writable but not sticky"
end
FileUtils.remove_entry path
end
else
path
end
end
```
When used explicitly with a directory, it raises an ArgumentError when the directory is world writable (File::Stat#world_writable?) but not sticky (File::Stat#sticky?). This is a normal behavior. But with how the method is written, the behavior is inconsistent and raises an ArgumentError only when using it with the block form. Worse, it raises the error in the ensure block instead of the first thing done in the method. So it raises the ArgumentError **after** it yields to the block, so after the job is already done.
Proof:
```ruby
irb(main):001:0> puts `ls -la /tmp`
total 4
drwxrwsrwx. 2 root 1000090000 6 Jan 22 10:02 .
drwxr-xr-x. 18 root root 4096 Jan 22 09:58 ..
=> nil
irb(main):002:0> # /tmp is non sticky but world writable
irb(main):003:0* Dir.mktmpdir(nil, '/tmp') do |tmpdir|
irb(main):004:1* puts "Hello, I'm using #{tmpdir}"
irb(main):005:1> end
Hello, I'm using /tmp/d20190122-26-5biuz2
ArgumentError: parent directory is world writable but not sticky
from /opt/rh/rh-ruby24/root/usr/share/ruby/tmpdir.rb:93:in `mktmpdir'
from (irb):3
from /opt/rh/rh-ruby24/root/usr/bin/irb:11:in `<top (required)>'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `load'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:74:in `kernel_load'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli/exec.rb:27:in `run'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli.rb:362:in `exec'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli.rb:22:in `dispatch'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/cli.rb:13:in `start'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/exe/bundle:30:in `block in <top (required)>'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
from /opt/rh/rh-ruby24/root/usr/local/share/gems/gems/bundler-1.15.4/exe/bundle:22:in `<top (required)>'
from /opt/rh/rh-ruby24/root/usr/bin/bundle:23:in `load'
from /opt/rh/rh-ruby24/root/usr/bin/bundle:23:in `<main>'
irb(main):006:0> puts `ls -la /tmp`
total 4
drwxrwsrwx. 3 root 1000090000 33 Jan 22 10:03 .
drwxr-xr-x. 18 root root 4096 Jan 22 09:58 ..
drwx--S---. 2 1000090000 1000090000 6 Jan 22 10:03 d20190122-26-5biuz2
=> nil
```
We can also see that the allocated directory **remains** after the exception is raised as the implementation raised in the ensure block.
An advisable implementation would be:
```ruby
def Dir.mktmpdir(prefix_suffix=nil, *rest)
path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
stat = File.stat(File.dirname(path))
if stat.world_writable? and !stat.sticky?
raise ArgumentError, "parent directory is world writable but not sticky"
end
if block_given?
begin
yield path
ensure
FileUtils.remove_entry path
end
else
path
end
end
```
This way, it will make the checks first and raise directly. And no temporary directory will be leaked with the block form.
As there is no maintainer for this lib, I can make a pull request with the following changes (with unit tests) if I'm asked to.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>