Bug #22271
closedRuby::Box fails to load C extensions from deep paths (temporary file name exceeds NAME_MAX)
Description
When a C extension is required inside a Ruby::Box, the temporary copy is named by flattening the full source path into a single file name (/ replaced with +). If the extension lives under a deep path, such as a long BUNDLE_PATH, that single name exceeds NAME_MAX (255 bytes on Linux and macOS) and open(2) fails with ENAMETOOLONG:
LoadError: can't prepare the extension file for Ruby Box (/tmp/_ruby_box_p123_3_+very+deep+...+date_core.so from /very/deep/.../date_core.so): can't open the file to write
Reproduction, from a build tree:
deep=/tmp/$(printf 'd%.0s' {1..90})/$(printf 'e%.0s' {1..90})/$(printf 'f%.0s' {1..90})
mkdir -p $deep
cp .ext/x86_64-linux/date_core.so $deep/
RUBY_BOX=1 ./ruby -e "require '$deep/date_core'"
I propose to stop embedding the source path in the file name: copy extensions into a process-private 0700 directory with an unpredictable name, and name each copy with a short per-process sequence number plus the basename. This also fixes #22110 (predictable temporary file names allow a local DoS).
Pull request: https://github.com/ruby/ruby/pull/18536
Updated by hsbt (Hiroshi SHIBATA) 21 days ago
- Status changed from Open to Closed
Fixed by https://github.com/ruby/ruby/pull/18536, merged as commit 6eba15864c4. Box-local extension copies now go into a process-private 0700 directory, and the copy file name no longer embeds the source path, so it stays within NAME_MAX regardless of the depth of the original path.
Updated by hsbt (Hiroshi SHIBATA) 21 days ago
The process-private directory introduced for this fix did not survive fork. A forked child inherits the cached directory path and removes it at exit, so later extension requires in the parent fail with the same LoadError. Fixed in https://github.com/ruby/ruby/pull/18578.
Updated by hsbt (Hiroshi SHIBATA) 21 days ago
- Related to Misc #22275: Ruby::Box support plan for RubyGems and Bundler added
Updated by hsbt (Hiroshi SHIBATA) 21 days ago
- Related to Bug #22110: Ruby::Box C-extension loading can be denied by predictable temporary filename added