Hi folks,

Since Ruby was tagged this morning, I'd like to ask for permission to fix the issue that I just encountered.

First, some background information. In glibc-2.32, the glibc developers implemented a wrapper for lchmod() and fchmodat() for POSIX compatibility. Unfortunately, the kernel is incompatible with these syscalls - they modify modes on symbolic links, which the kernel does not support. The relevant entry in the libc-announce email is here: https://sourceware.org/pipermail/libc-announce/2020/000029.html (look for [14578] libc: /proc-based emulation for lchmod, fchmodat). The Ruby FileUtils library expects that the operation not return EOPNOTSUPP, which is what the kernel returns if that syscall is attempted. This behavior is similar to what's implemented in musl libc (again for POSIX compatibility). However, lchmod() is unsupported at the kernel level. Ruby is expecting a POSIX compliant system, and in this case, lchmod() isn't supported, so it's failing. This is similar to the libarchive problem that I fixed yesterday, where some functions would output EOPNOTSUPP.

This issue is evident in the test suite, where the tests crash after the first portion of the test suite is complete:

# Running tests:

Leaked file descriptor: DRbTests::TestDRbTCP#test_immediate_close: 9 : #<IO:fd 9>

  1) Failure:
TestFileUtils#test_cp_r_symlink_preserve [/sources/ruby-2.7.1/ruby-2.7.1/test/fileutils/test_fileutils.rb:439]:
Exception raised:
<#<Errno::ENOTSUP: Operation not supported @ apply2files - tmp/cross2/b/l>>.

  2) Failure:
TestNotImplement#test_respond_to_lchmod [/sources/ruby-2.7.1/ruby-2.7.1/test/ruby/test_notimp.rb:17]:
<false> expected but was
<true>.

  3) Error:
TestNotImplement#test_call_lchmod:
Errno::ENOTSUP: Operation not supported @ apply2files - /tmp/d20200817-26691-1iz31al/g
    /sources/ruby-2.7.1/ruby-2.7.1/test/ruby/test_notimp.rb:60:in `lchmod'
    /sources/ruby-2.7.1/ruby-2.7.1/test/ruby/test_notimp.rb:60:in `block in test_call_lchmod'
    /sources/ruby-2.7.1/ruby-2.7.1/lib/tmpdir.rb:89:in `mktmpdir'
    /sources/ruby-2.7.1/ruby-2.7.1/test/ruby/test_notimp.rb:54:in `test_call_lchmod'

  4) Error:
TestPathname#test_lchmod:
Errno::ENOTSUP: Operation not supported @ apply2files - l
/sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:820:in `lchmod' /sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:820:in `lchmod' /sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:820:in `block in test_lchmod' /sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:340:in `block (2 levels) in with_tmpchdir'
/sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:339:in `chdir'
/sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:339:in `block in with_tmpchdir'
    /sources/ruby-2.7.1/ruby-2.7.1/lib/tmpdir.rb:89:in `mktmpdir'
/sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:337:in `with_tmpchdir' /sources/ruby-2.7.1/ruby-2.7.1/test/pathname/test_pathname.rb:814:in `test_lchmod'


I have a hunch that this might impact either SWIG or Subversion w/ ruby bindings, or potentially both. The reason why I think Subversion's ruby bindings could be affected has to do with the 'svn link' function.

There is a fix for it upstream, although it requires modifications because it expects only Musl Libc to be affected, and FreeBSD. The patch needs to be modified to include standard Linux as well. The patch also needs to be modified to modify the spec/ruby/core/file/lchmod_spec.rb file to adjust to expectations from glibc-2.32 (false to true).

The patch can be found here: https://git.ruby-lang.org/ruby.git/commit/?id=a19228f878d955eaf2cce086bcf53f46fdf894b9


After applying this, the normal two test failures for clock and getaddrinfo still continue to happen, but no other regressions are experienced:

1)
File.utime allows Time instances in the far future to set mtime and atime FAILED
Expected 2446 == 559444
to be truthy but was false
/sources/ruby-2.7.1/ruby-2.7.1/spec/ruby/core/file/utime_spec.rb:78:in `block (4 levels) in <top (required)>' /sources/ruby-2.7.1/ruby-2.7.1/spec/ruby/core/file/utime_spec.rb:3:in `<top (required)>'

2)
Socket.getnameinfo using IPv6 using a 3 element Array as the first argument using NI_NUMERICHOST as the flag returns an Array containing the numeric hostname and service name ERROR
SocketError: getaddrinfo: Name or service not known
/sources/ruby-2.7.1/ruby-2.7.1/spec/ruby/library/socket/socket/getnameinfo_spec.rb:111:in `getnameinfo' /sources/ruby-2.7.1/ruby-2.7.1/spec/ruby/library/socket/socket/getnameinfo_spec.rb:111:in `block (6 levels) in <top (required)>' /sources/ruby-2.7.1/ruby-2.7.1/spec/ruby/library/socket/socket/getnameinfo_spec.rb:65:in `<top (required)>'

Finished in 31.352756 seconds

3746 files, 30429 examples, 171113 expectations, 1 failure, 1 error, 0 tagged
make: *** [uncommon.mk:822: yes-test-spec] Error 1


I would like permission to integrate this patch into the book.


- Doug

--
http://lists.linuxfromscratch.org/listinfo/blfs-dev
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to