An interpreter of object-oriented scripting language
Go to file
Jarek Prokop 46b6a33dba Fix RCE vulnerability with .rdoc_options in RDoc (CVE-2024-27281).
The patch contains 2 commits, 1 from upstream that comes from
7957a25edf
which is a commit present in Ruby 3.0 branch. That is the closest Ruby
version to 2.5 that contains the CVE fix.

2nd fix is made as a downstream adjustment to the YAML calls used
in the fix.
While upstream relies on `YAML::safe_load_file` method, Ruby 2.5.9's
YAML module contains no such method.
To not introduce new RHEL exclusive downstream logic into the RDoc library,
the `YAML::safe_load_file` method was copied from Ruby 3.3.0's
sources: https://github.com/ruby/ruby/blob/v3_3_0/ext/psych/lib/psych.rb#L658

In psych this was first introduced in:
0210e310d0 (diff-659eac8589abc82c9a0ab3699e4e4be4774d9c09c6c9934af5d9dae0d264439cR592)
In Ruby 3.0 this capability was added with this commit:
c2a60fec2f (diff-87e1cb3017e15fc7f32c0bc0144934204bde9a56849dcd0cde864118e95ea38cR591)
Since then it had not changed up to Ruby 3.3, therefore it does not make a
difference whether the method was copied from Ruby 3.0.0 or Ruby 3.3.0.

The method is very simple, it is a `File.open` call that then provides the open
file as a readable object containing YAML. One more thing of note is
`r:bom|utf-8`, which essentially opens the YAML file in reading mode
utilizing Unicode BOM to help determine encoding, if the BOM is missing,
the utf-8 is used instead. 2.5 documentation Reference:
https://docs.ruby-lang.org/en/2.5.0/IO.html#method-c-new-label-IO+Encoding
. Additionally, in the YAML function there is a non-optional argument `filename`.
It is used to give more information in exceptions with the `YAML::safe_load`.

While the `YAML::safe_load_file` did not change from Ruby 3.0.0 up to at least
the marked 3.3.0 commit, `YAML::safe_load` went through a function argument
transformation, where, between Ruby 2.6 and the 3.0 timeframe the arguments
that can be provided to the method changed from regular positional
arguments to keyword arguments. Upstream's CVE fix, both in the test
files and in the actual source code counts with this capability. This is
especially important to the `permitted_classes:` keyword argument, that
is part of the CVE's mitigation.

To keep upstream logic even in Ruby 2.5, we have to:
1) Copy the YAML.safe_load_file logic
2) Provide the arguments to `YAML::safe_load` correctly to keep with the
   `YAML::safe_load_file` behavior.

Doing step 1 is a bit tricky. We do not want to backport that method, as
that would extend Ruby 2.5.9's capabilities beyond what was intended
upstream.

Therefore it seems better, as the `YAML.safe_load_file` method is only
called once in that entire upstream patch, to just copy-paste the logic.
This is then only internal to RDoc and achieves functional parity with
the upstream patch.

For step 2, it is necessary to keep in mind how `YAML::safe_load` looks
in Ruby 2.5 vs Ruby 3.0--Ruby 3.3
Ruby 2.5:
https://github.com/ruby/ruby/blob/v2_5_9/ext/psych/lib/psych.rb#L313
Ruby 3.0:
https://github.com/ruby/ruby/blob/v3_0_0/ext/psych/lib/psych.rb#L329
Ruby 3.3:
https://github.com/ruby/ruby/blob/v3_3_0/ext/psych/lib/psych.rb#L322

And also how the arguments will be provided to `YAML::safe_load_file`.

While Ruby 2.5 has all the arguments for `safe_load` positional,
Ruby 3.0 has a mix, where they have deprecated positional arguments in
favor of keyword arguments, but kept the positional arugments around for that
time. Judging by the prepended "legacy_" on the arguments, they were
kept around for compatibility.
Ruby 3.3 does not contain positional arguments at all and only contains
keyword arguments

Let's consider the difference between Ruby 2.5's and Ruby 3.3.0's `YAML::safe_load`.
(While we could use Ruby 3.0.0 here, it is better to use Ruby 3.3. The
newer Ruby provides us with a clearer look at the method arguments. Mainly caused
by the fact that upstream only uses keyword arguments, so for the
purposes of the upstream CVE patch that only uses keyword arguments,
they are effectively identical for us)
Then let's also consider what is required to provide to the copy-pasted
`YAML::safe_load` internal to `YAML::safe_load_file` from Ruby 3.3
to keep equivalent semantic in RDoc.

Ruby 2.5 defines the function with arguments as:
~~~
  def self.safe_load yaml, whitelist_classes = [], whitelist_symbols = [], aliases = false, filename = nil, symbolize_names: false
~~~
and Ruby 3.3 defines the function with arguments as:
~~~
  def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
~~~

We should focus on 2 things. Defaults and naming.
Naming changed due to
682abf20f0
but despite that, the ordering remained the same for the arguments we care
about so we can compare them more directly when we look past the
difference of positional vs keyword arguments.

From the Ruby 3.3 `YAML::safe_load_file`'s definition
~~~
  def self.safe_load_file filename, **kwargs
    File.open(filename, 'r:bom|utf-8') { |f|
      self.safe_load f, filename: filename, **kwargs
    }
  end
~~~
we already can assume that we will need to provide the correct filename
to both the File.open and the `YAML::safe_load` since it is provided
here.

From the upstream RDoc CVE patch:
7957a25edf (diff-a4c824fbc4e6e86217cec1b940a70536a4134afc08cbd8083a0340407d714b3aR165)
we can see the way `YAML::safe_load_file` is used in `lib/rdoc/rdoc.rb`:
~~~
      options = YAML.safe_load_file '.rdoc_options', permitted_classes: [RDoc::Options, Symbol]
~~~
We know that the first argument for the `YAML::safe_load_file` is
`filename`, and `permitted_classes` argument is passed into the method.
As hinted earlier, keyword arguments other than filename are passed in via
`**kwargs`, so there is no special handling around them and it is like
we would be calling the underlying `YAML::safe_load` with that keyword
argument directly.

Also studying the differences in `YAML::safe_load` between Ruby 2.5 and 3.3
as noted in the Ruby documentation:
Ruby 2.5: https://docs.ruby-lang.org/en/2.5.0/Psych.html#method-c-safe_load
Ruby 3.3: https://docs.ruby-lang.org/en/3.3/Psych.html#method-c-safe_load
the `whitelist_classes` in 2.5 and `permitted_classes` in 3.3 are
equivalent and are serving the same purpose.
So, we can provide the value to permitted_classes as the 2nd
positional argument to `YAML::safe_load` without using the keyword.
This applies also to the downstream test file adjustments.

However, to achieve parity with the upstream code in `lib/rdoc/rdoc.rb` we
also have to pay attention to correctly utilizing the `filename` argument.
The upstream patch only uses the `.rdoc_options` file, therefore
we can safely hardcode that value into the calls, replacing the argument in the
mentioned `YAML::safe_load_file` downstream implementation.

However, in Ruby 2.5 we also have to pay attention to where `filename` is
provided. There are multiple keyword arguments that are not used
upstream, we are not using them as well. However since the arguments are
positional we have to provide default values to the arguments preceding
the `filename` argument in the `YAML::safe_load` call to keep the
behavior as it was implemented upstream.

Therefore our downstream `YAML::safe_load_file` replacement in the
`lib/rdoc/rdoc.rb` looks like this:
~~~
      options = File.open('.rdoc_options', 'r:bom|utf-8') do |file|
        YAML.safe_load file, [RDoc::Options, Symbol], [], false, '.rdoc_options'
      end
~~~
If we imagine this without `options = ` this is almost the same as the
Ruby 3.3 `YAML.safe_load_file`. The key difference here is hardcoded
`filename` arguments to both `File::open` and `YAML::safe_load`.
But as `filename` is the 5th argument and we only filled the first 2
arguments, we have to fill the arguments in-between with their default
values. Namely, upstream does not utilize equivalents to
`whitelist_symbols` and `aliases`. Their default are, in-order, `[]` and
`false`, so we insert them in between. Then we provide the '.rdoc_options'
as the `filename`, to make sure it will be provided in a potential exception
from YAML in the case of having failed to parse the file.

Resolves: RHEL-34117
2024-06-24 19:39:15 +02:00
.gitignore Fix import. 2023-06-07 11:58:34 +02:00
abrt_prelude.rb Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
libruby.stp Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
macros.ruby Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
macros.rubygems Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
operating_system.rb Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-1.9.3-mkmf-verbose.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.1.0-Allow-to-specify-additional-preludes-by-configuratio.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.1.0-always-use-i386.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.1.0-custom-rubygems-location.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.1.0-Enable-configuration-of-archlibdir.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.1.0-Prevent-duplicated-paths-when-empty-version-string-i.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.2.3-Generate-preludes-using-miniruby.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.3.0-ruby_version.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.5.0-Add-Gem.operating_system_defaults.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.5.1-Avoid-need-of-C++-compiler-to-pass-the-test-suite.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.5.9-revert-stop-the-error-due-to-openssl-1-1-1h.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-config-support-include-directive.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-configure-fstack-protector-strong.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-Fix-issues-detected-by-code-analysis-tool.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-library-options-to-MAINLIBS.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-rdoc-6.0.2-check-nil-text-token.patch Fix rdoc parsing of nil text tokens. 2023-06-07 11:58:34 +02:00
ruby-2.6.0-rdoc-6.0.2-fix-different-js-gz-pages-across-multilib.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.0-use-larger-keys-for-SSL-tests.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.3-fiddle-1.0.0-ffi-closure-alloc-default.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.8-net-ftp-pasv-can-connect-to-arbitrary-host.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.8-net-imap-startls-stripping-vulnerability.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.8-rdoc-6.1.2.1-command-injection-vulnerability.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.9-cgi-0.1.1-cookie-parse-not-decode-names.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.9-date-2.0.1-parse-length-limit.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-2.6.10-Fix-CVE-2022-28739-Buffer-overrun-in-str2float.patch Fix buffer overrun in String-to-Float conversion. 2023-06-26 13:41:10 +02:00
ruby-2.7.7-Fix-CVE-2021-33621-HTTP-response-splitting-in-CGI.patch Fix HTTP response splitting in CGI. 2023-06-22 15:19:31 +02:00
ruby-2.7.8-Fix-CVE-2023-28755-ReDos-vulnerability-in-URI.patch Fix ReDoS vulnerability in URI. 2023-06-26 13:41:10 +02:00
ruby-2.7.8-Fix-CVE-2023-28756-ReDoS-vulnerability-in-Time.patch Fix ReDoS vulnerability in Time. 2023-06-26 13:41:10 +02:00
ruby-3.0.0-Convert-ip-addresses-to-canonical-form.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-3.0.3-fiddle-1.0.8-Rely-on-hard-coded-lib-name-to-detect-glibc.patch Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby-3.0.7-Fix-CVE-2023-36617-Upstreams-incomplete-fix-for-CVE-2023-28755.patch Fix ReDoS vulnerability - upstream's incomplete fix for CVE-2023-28755. 2024-06-17 19:29:34 +02:00
ruby-3.0.7-Fix-CVE-2024-27280-Buffer-overread-in-StringIO.patch Fix Buffer overread vulnerability in StringIO (CVE-2024-27280). 2024-06-17 19:30:01 +02:00
ruby-3.0.7-Fix-CVE-2024-27281-RCE-vulnerability-with-rdoc_options.patch Fix RCE vulnerability with .rdoc_options in RDoc (CVE-2024-27281). 2024-06-24 19:39:15 +02:00
ruby-3.1.3-Fix-for-tzdata-2022g.patch Fix Ruby test failures regarding tzdata and git. 2023-06-22 15:18:50 +02:00
ruby-3.2.0-git-2.38.1-fix-rubygems-test.patch Fix Ruby test failures regarding tzdata and git. 2023-06-22 15:18:50 +02:00
ruby-3.4.0-ruby-net-http-Renew-test-certificates.patch Renew test certificates for net-http tests. 2024-06-17 19:28:51 +02:00
ruby-exercise.stp Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
ruby.spec Fix RCE vulnerability with .rdoc_options in RDoc (CVE-2024-27281). 2024-06-24 19:39:15 +02:00
rubygem-cgi-0.3.6-Loosen-the-domain-regex-to-accept-dot.patch Let cookies use leading dot in the domain to retain compatibility. 2023-06-26 13:40:21 +02:00
rubygems.attr Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
rubygems.con Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
rubygems.prov Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
rubygems.req Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
sources Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-23 23:50:08 -05:00
test_abrt.rb Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00
test_systemtap.rb Import rpm: 6a79cc8230d437ba4c0e950842723d4d37ce3c11 2023-02-20 02:13:04 -05:00