Fiddle::Closure object is making use of FFI closure
from libffi. When such object is created (instantiated) in Ruby,
and then the process forks on an SELinux-enabled system, the memory
will become corrupted. That is usually not a problem until the
The garbage collector sweeps the object and tries to free it, in which case the
Ruby process will fail with signal SIGABRT.
Tests in test/fiddle/test_closure.rb, test/fiddle/test_func.rb,
and test/fiddle/test_function.rb use the `Fiddle::Closure` class
directly and fiddle/test_import.rb use the class indirectly through
`bind_function` method, therefore they are disabled to prevent
introducing the problematic object into the Ruby GC during test suite
execution instead of relying on that fork and subsequent
garbage collection will not happen.
If an FFI closure object is allocated in Ruby
and the `fork` function is used afterward, the memory
pointing to the closure gets corrupted, and if Ruby GC
tries to collect the object in that state, a SIGABRT
error occurs.
The minimal Ruby reproducer for the issue is the following:
~~~
$ cat fiddle_fork.rb
require 'fiddle/closure'
require 'fiddle/struct'
Fiddle::Closure.new(Fiddle::TYPE_VOID, [])
fork { }
GC.start
~~~
We allocate an unused Closure object,
so it is free for the GC to pick up. Before we call `GC.start`
we fork the process as that corrupts the memory.
Running this with ruby-3.1.2-167.fc37.x86_64 on SELinux enabled system:
~~~
$ ruby fiddle_fork.rb
Aborted (core dumped)
~~~
Such issues may appear at random (depending on the use of forking and GC)
in larger applications that use Fiddle::Closure but can be spotted by the
following functions appearing in the coredump backtrace:
~~~
0x00007f6284d3e5b3 in dlfree (mem=<optimized out>) at ../src/dlmalloc.c:4350
0x00007f6284d6d0b1 in dealloc () from /usr/lib64/ruby/fiddle.so
0x00007f6295e432ec in finalize_list () from /lib64/libruby.so.3.1
0x00007f6295e43420 in finalize_deferred.lto_priv () from /lib64/libruby.so.3.1
0x00007f6295e4ff1c in gc_start_internal.lto_priv () from /lib64/libruby.so.3.1
~~~
Possible solutions to prevent Ruby from crashing:
* Do not use Fiddle::Closure.
* Use the Fiddle::Closure object only in isolated subprocess that
will not fork further.
* Enable static trampolines in libffi as noted in bugzilla comment:
<https://bugzilla.redhat.com/show_bug.cgi?id=2040380#c9>
See related discussion on
<https://bugzilla.redhat.com/show_bug.cgi?id=2040380>
Ruby upstream ticket:
<https://bugs.ruby-lang.org/issues/18914>
Ruby Fiddle ticket:
<https://github.com/ruby/fiddle/issues/102>
RPM 4.18.0-beta1 or later versions remove the build directory
automatically, the build fails on removing temporary directories with
the missing 'w' bit.
RubyGems contain this patch since version 3.3.8.
This was merged to ruby_3_1 branch in upstream ruby, but it is not
included in the v3_1_2 tag, so new Ruby 3.1 release should contain this
change.
Relevant RPM upstream PR: https://github.com/rpm-software-management/rpm/pull/2080
Relevant bug: https://bugzilla.redhat.com/show_bug.cgi?id=2105393
Previous commit changed GC compaction methods to not be implemented
when not supported. However, that commit only does compile time checks,
but there are additional compaction support checks during run time.
This commit changes it so that GC compaction methods aren't defined
also during run time if the platform does not support GC compaction.
The patch is manually backported from following change set:
https://github.com/ruby/ruby/pull/60192c19086323
To apply the patch included with this commit,
first apply `ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch`
and then apply the `ruby-3.2.0-detect_compaction_support_during_runtime.patch`.
Related upstream issue: https://bugs.ruby-lang.org/issues/18829
The patch implements the methods as rb_f_notimplement.
To test for compaction users can now use `GC.respond_to?(:compact)`.
The upstream patch relies on the macro `GC_COMPACTION_SUPPORTED`
that is defined when the `__wasi__` is false. The define is defined by
an arch conditional in the specfile, which is not optimal but works in our case.
663833b08fhttps://bugs.ruby-lang.org/issues/18829
This also requires regenerating the gc.rbinc and miniprelude.c
since the patch touches gc.rb. This patch is available in
ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch.
To regenerate the gc.rbinc and miniprelude.c files patch:
~~~
tar -Jxvf ./ruby-3.1.2.tar.xz
git clone https://github.com/ruby/ruby.git
cd ruby && git checkout v3_1_2
patch -p1 < ../ruby-3.2.0-define-unsupported-gc-compaction-methods-as-rb_f_notimplement.patch
./autogen.sh && ./configure
make gc.rbinc miniprelude.c
cd ..
diff -u {ruby-3.1.2,ruby}/gc.rbinc > ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
diff -u {ruby-3.1.2,ruby}/miniprelude.c >> ruby-3.2.0-define-unsupported-gc-compaction-methods_generated-files.patch
~~~
Uptream bug: https://bugs.ruby-lang.org/issues/18779
Upstream PR: https://github.com/ruby/ruby/pull/5934
According to the <https://bugs.ruby-lang.org/issues/18756>, the `Q=` is not
recommended. The `V=1` is recommended to output for the verbose mode.
The `make V=1` suppresses some logs that `make` without `V=1` outputs rather
than just adding verbose logs.
While the `V=1 ECHO0=echo` is more equivalent with `Q=`, the
`make V=1 ECHO0=echo` doesn't really output meaningful logs additionally.
So, the `make V=1` is the best option for us to check the compiler flags.
Because the `%make_build` macro includes the `V=1`. Note there is no actual
difference of build.log between before and after this commit.
```
$ rpm --eval %make_build
/usr/bin/make -O -j8 V=1 VERBOSE=1
```
Because the gem extensions were built in `%{buildroot}` they referred
`BUILDROOT` directory, which would be under normal circumstances
reported by RPM, but there was a bug in RPM due to changes in grep:
https://github.com/rpm-software-management/rpm/issues/1968
* Add `make test-bundler-parallel` executed on the upstream CI.
See <41a48535d1/.github/workflows/ubuntu.yml (L22)>.
* The tests are disabled as a default, as it requires the internet.
Run the Bundler tests as follows.
```
$ mock --with bundler_tests ruby-3.1.0-161.fc37.src.rpm
```
* Fix a test for `bin/bundle update --bundler` in `make test-bundler`.
This error is gone as false positive in rpmlint 2.0+. However the rpmlint
version on Zuul CI running on the Fedora 34 container is still 1.11. After Zuul
CI is upgraded to Fedora 35+ container, and uses the rpmlint 2, we can notice
this filter is not used by "E: unused-rpmlintrc-filter" error, and remove it.
This replaces the parts of the original PR with official patches which
landed in [ruby/openssl](https://github.com/ruby/openssl) repository and
should reflect the state of OpenSSL 3 support in Ruby 3.1.
In Ruby 3.0.3, a new logic with the hard-coded "libc.so.6" to detect glibc
works on PPC, both Power 8 and 9.
See <https://bugs.ruby-lang.org/issues/12666#note-13>.
Note the logic also fixes the following error on a Power 9 environment where
the path is `/lib64/glibc-hwcaps/power9/libc-2.28.so`.
```
/builddir/build/BUILD/ruby-2.6.9/.ext/common/fiddle/import.rb:299:in `import_function': cannot find the function: strcpy() (Fiddle::DLError)
from /builddir/build/BUILD/ruby-2.6.9/.ext/common/fiddle/import.rb:172:in `extern'
from /builddir/build/BUILD/ruby-2.6.9/test/fiddle/test_import.rb:17:in `<module:LIBC>'
from /builddir/build/BUILD/ruby-2.6.9/test/fiddle/test_import.rb:10:in `<module:Fiddle>'
from /builddir/build/BUILD/ruby-2.6.9/test/fiddle/test_import.rb:9:in `<top (required)>'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:958:in `require'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:958:in `block in non_options'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:952:in `each'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:952:in `non_options'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:64:in `process_args'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:130:in `process_args'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:1136:in `process_args'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:1141:in `run'
from /builddir/build/BUILD/ruby-2.6.9/test/lib/test/unit.rb:1148:in `run'
from ./test/runner.rb:33:in `<main>'
```
- Fix command injection vulnerability in RDoc.
Resolves: CVE-2021-31799
- Fix FTP PASV command response can cause Net::FTP to connect to arbitrary host.
Resolves: CVE-2021-31810
- Fix StartTLS stripping vulnerability in Net::IMAP.
Resolves: CVE-2021-32066
- Fix dependencies of gems with explicit source installed from a different
source.
Resolves: CVE-2020-36327
A result of ruby.spec file depends on how the spec file is called by rpmlint.
```
$ rpmlint ruby.spec
ruby.spec:20: E: use-of-RPM_SOURCE_DIR
..
0 packages and 1 specfiles checked; 3 errors, 4 warnings.
$ rpmlint ./ruby.spec
./ruby.spec:20: E: use-of-RPM_SOURCE_DIR
..
0 packages and 1 specfiles checked; 3 errors, 4 warnings.
```
Nothing referred and no dependency information should be no problem.
Ignore the following error.
```
ruby-libs.x86_64: E: shared-lib-without-dependency-information /usr/lib64/ruby/enc/gb2312.so
```
The `chroot` in the `dir.c` is just used as a Ruby binding `Dir.chroot`
for the function.
Ignore the following error.
```
ruby-libs.x86_64: E: missing-call-to-chdir-with-chroot /usr/lib64/libruby.so.3.0.1
```
The FTBFS has started to happen with rpm-4.16.90-0.git15395.2.fc35.
root.log
```
DEBUG util.py:444: error: line 116: Unknown tag: /chroot_tmpdir/srpm_unpacked/SOURCES/macros.ruby
```
As the `%{?load:...}` is undocumented, it is gone.
https://github.com/rpm-software-management/rpm/issues/1669